什么时候有人需要创建延期?

时间:2015-09-29 20:22:46

标签: javascript promise ecmascript-6 bluebird es6-promise

现在看来,创建延迟对象通常不鼓励使用ES6风格的Promise构造函数。是否存在使用延迟的必要(或者更好地某种方式)的情况?

例如,在this page上,以下示例作为使用延迟的理由:

function delay(ms) {
    var deferred = Promise.pending();
    setTimeout(function(){
        deferred.resolve();
    }, ms);
    return deferred.promise;
}

但是,这可以使用Promise构造函数完成:

function delay(ms) {
    return new Promise(function(resolve, reject){
        setTimeout(function(){
            resolve();
        }, ms);
    });
}

2 个答案:

答案 0 :(得分:5)

  

是否存在必要的情况(或者只是   更好的某种方式)使用延迟?

没有必要延期的情况。 “更好”是一个意见问题,所以我不会在这里解决。

ES6 promise规范没有延迟对象是有原因的。 您根本不需要。人们过去使用延迟对象的任何内容都可以始终以不使用延迟对象的其他方式完成。

首先,大多数用法非常适合promise构造函数模型。其次,任何其他不完全适合该模型的情况仍然可以通过promise构造函数完成,或者从已解决的promise开始并链接到它。

我看到延迟的主要用例是当你想要将resolve()reject()的能力传递给除了创建承诺的代码之外的其他代码。延迟使得非常简单,因为您可以只传递延迟对象,并且它具有解析或拒绝它的公共方法。但是,有了承诺,您也可以通过resolve和/或reject方法。由于它们自动绑定到特定对象,因此您只需传递函数引用即可。而且,在其他情况下,您可以让其他代码创建自己的承诺并自行解决/拒绝它,并将该操作链接到您的,而不是让他们解决/拒绝您的承诺。这一切都像传递延迟对象一样干净吗?主要是意见问题,但两者都不是非常常见的用例,所有这些都可以在没有单独的延迟对象的情况下完成。

而且,正如torazaburo指出的那样,让一些外部代码解决或拒绝你的承诺本身就是一种反模式。您创建了承诺 - 您解决/拒绝承诺。如果您想使用外部事件来决定何时解决/拒绝它,那么让他们通知您(通过他们自己的承诺或回调),您可以解决/拒绝您自己的承诺。或者,让他们创建自己的承诺,你可以使用。这真的是理想的模型。或者,让他们链接到你的诺言,以便在他们的操作完成时给出最终结果。

如果一个人习惯使用延迟对象进行编码(比如延迟使用jQuery),那么在没有它的情况下可能需要稍微习惯编码,但过了一会儿你就开始以不同的方式思考它开始变得自然只使用promise构造函数。

一旦你宣传了在任何给定应用程序中使用的异步操作的范围,你甚至不需要再创建自己的承诺了,因为你大多只是建立你所称的异步函数的承诺创建或使用Promise.all()等流量控制操作,为您创建超级承诺。

这是反模式的要点。 使用已为您创建的承诺,而不是手动创建更多。链接它们。返回.then()处理程序的承诺,以在逻辑控制下链接异步操作。

当然,现有的异步操作不返回有人需要创建承诺的promises,但是应该在promisify层中完成,而不是在主编码逻辑的提供之外的地方,并且只执行一次操作然后调用异步操作的代码应该只能使用返回的promises。

答案 1 :(得分:4)

Native Promises没有延迟开箱即用的所有内置方法,例如解析其构造函数范围之外的promise的方法(虽然很容易用native native实现),以及能够查看承诺的状态(在本机Promise中隐藏常规JavaScript,但可以在开发工具中检查)。

今天使用延迟的主要原因是向后兼容依赖于这些额外方法的代码。如果不踩到意见领域,很难给出明确的答案。