是否存在需要(或更好地)使用延迟的情况?
没有这种情况需要延期。“更好”是一个见仁见智的问题,所以我不会在这里解决这个问题。
ES6 Promise规范没有延迟对象是有原因的。 你根本不需要一个。 人们过去使用延迟对象的任何事情都可以用另一种不使用延迟对象的方式来完成。
首先,大多数用途非常适合Promise构造函数模型。其次,任何其他不完全适合该模型的情况仍然可以使用 promise 构造函数或从已解决的 promise 开始并链接到它来完成。
我见过的 deferred 的主要用例是,当您想要将功能传递给resolve()
或reject()
关闭除创建Promise的代码之外的其他代码段时。Deferred 使这变得非常容易,因为您可以只传递 deferred 对象,并且它具有用于解决或拒绝它的公共方法。但是,有了Promise,您也可以通过resolve
和/或reject
方法。由于它们自动绑定到特定对象,因此您只需传递函数引用即可。而且,在其他情况下,您可以让其他代码创建自己的Promise并自行解决/拒绝它,并将该操作链接到您的操作,而不是让他们解决/拒绝您的Promise。所有这一切都和传递一个延迟对象一样干净吗?主要是见仁见智,但都不是很常见的用例,所有这些都可以在没有单独的延迟对象的情况下完成。
而且,正如 torazaburo 指出的那样,让一些外部代码解决或拒绝您的Promise本身就是一种反模式。您创建了Promise - 您解决/拒绝了它。如果您想使用外部事件来决定何时解决/拒绝它,那么让他们通知您(通过他们自己的Promise或回调),您可以解决/拒绝您自己的Promise。或者,让他们创建自己可以使用的Promise。这才是真正想要的模型。或者,让他们链接到您的Promise上,以便在他们的操作完成时控制最终结果。
如果人们习惯于使用延迟对象进行编码(比如使用 jQuery 延迟),可能需要一点时间来适应没有它的编码,但是过了一会儿,您就会开始不同的思考,并且开始变得自然而然就可以使用Promise构造函数。
一旦您Promise了您在任何给定应用程序中使用的异步操作领域,您甚至不再需要创建自己的Promise就非常罕见了,因为您大多只是构建您调用的异步函数已经创建或使用的Promise流控制操作,例如Promise.all()
为您创建超级Promise。
这是反模式的要点。 使用已经为您创建的Promise,而不是手动创建更多Promise。 把它们锁起来。从.then()
处理程序返回Promise以在逻辑控制下链接异步操作。
当然,现有的异步操作不会返回需要有人为其创建Promise的Promise,但这应该在主要编码逻辑范围之外的某个地方的Promise层中完成,并且只为该操作完成一次,然后调用异步操作的代码应该能够只使用返回的Promise。