什么时候需要创建一个延迟? [英] When would someone need to create a deferred?

查看:52
本文介绍了什么时候需要创建一个延迟?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现在似乎普遍不鼓励创建延迟对象,而倾向于使用 ES6 风格的 Promise 构造函数.是否存在需要(或更好地)使用延迟的情况?

It seems generally that creating deferred objects is now commonly discouraged in favor of using the ES6-style Promise constructor. Does there exist a situation where it would be necessary (or just better somehow) to use a deferred?

例如,在此页面,以下示例是使用延迟的理由:

For example, on this page, the following example is given as justification for using a deferred:

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

然而,使用 Promise 构造函数也可以做到这一点:

However, this could be done just as well with the Promise constructor:

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

推荐答案

是否存在需要(或只是以某种方式更好)使用延迟?

Does there exist a situation where it would be necessary (or just better somehow) to use a deferred?

没有这种情况需要延迟.更好"是一个见仁见智的问题,所以我不会在这里解决这个问题.

There is no such situation where a deferred is necessary. "Better" is a matter of opinion so I won't address that here.

ES6 承诺规范没有延迟对象是有原因的.你根本不需要.人们过去使用延迟对象的任何事情都可以总是用另一种不使用延迟对象的方式来完成.

There's a reason that the ES6 promise specification does not have a deferred object. You simply don't need one. Anything that people used to use a deferred object for can always be done another way that doesn't use a deferred object.

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

First off, the majority of uses fit very nicely into the promise constructor model. Secondly, any other cases that didn't fit quite so cleanly into that model can still be accomplished with the promise constructor or by starting with a resolved promise and chaining to it.

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

The main use case I've seen for a deferred is when you want to pass the ability to resolve() or reject() off to some other piece of code other than the code that created the promise. A Deferred made that very easy since you could just pass the deferred object and it had public methods for resolving or rejecting it. But, with a promise, you can also just pass the resolve and/or reject methods. Since they are bound to the specific object automatically, you can just pass the function references. And, in other cases, you can just let the other code create their own promise and resolve/reject it themselves and have that operation linked to yours rather than letting them resolve/reject your promise. Is all that quite as clean as passing a deferred object? Mostly a matter of opinion, but neither are very common use cases and all are something that can be accomplished without a separate deferred object.

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

And, as torazaburo points out, letting some external code resolve or reject your promise is a bit of an anti-pattern in its own right. You created the promise - you resolve/reject it. If you want to use external events to decide when to resolve/reject it, then have them notify you (via their own promise or callback) and you can resolve/reject your own promise. Or, have them create their own promise that you can use. That's really the desired model. Or, let them chain onto your promise so that the end result is gated by when their operation is done.

如果人们习惯于使用延迟对象进行编码(比如使用 jQuery 延迟),可能需要一点时间来适应没有它的编码,但过了一会儿,你就会开始不同的思考,它开始变得自然只使用承诺构造函数.

If one was used to coding with the deferred object (say with a jQuery deferred), it might take a little getting used to coding without it, but after a little while you just start to think differently and it starts to come natural to just use the promise constructor.

一旦您承诺了您在任何给定应用程序中使用的异步操作领域,您甚至不再需要创建自己的承诺就非常罕见了,因为您大多只是构建了您调用的异步函数已经存在的承诺创建或使用诸如 Promise.all() 之类的流控制操作,它们为您创建超级承诺.

Once you promisify the sphere of async operations that you use in any given application, it's pretty rare that you ever even need to create your own promises any more because you are mostly just building off promises that the async functions you call are already creating or using flow control operations like Promise.all() which create uber promises for you.

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

This is the main point of anti-patterns. Use the promises that are already created for you rather than manually create more. Chain them. Return promises from .then() handlers to link async operations under logic control.

当然,现有的异步操作不会返回需要有人为其创建承诺的承诺,但这应该在主要编码逻辑的供应范围之外的某个地方的承诺层中完成,并且为此只执行一次操作,然后调用异步操作的代码应该能够只使用返回的承诺.

Of course, there are existing async operations that don't return promises for which somebody needs to create a promise, but that should be done in a promisify layer somewhere outside the purvey of your main coding logic and done only once for that operation and then code that calls the async operation should be able to just use the returned promises.

这篇关于什么时候需要创建一个延迟?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆