admin管理员组文章数量:1336604
It seems generally that creating deferred objects is now monly 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;
}
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);
});
}
It seems generally that creating deferred objects is now monly 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;
}
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);
});
}
Share
Improve this question
asked Sep 29, 2015 at 20:22
xyzxyz
1,4972 gold badges13 silver badges18 bronze badges
5
- The cases where you'd use the promise constructor are pretty rare too. For what it's worth. – Benjamin Gruenbaum Commented Sep 29, 2015 at 21:02
-
As Benjamin Gruenbaum said, you would seldom need to even use
new Promise
. Your example above is a case in point. A delay promise that resolves toundefined
is not very useful. You would typically want to delay an existing promise e.g.somPromise.delay(t).then(...)
, in which case your delay would not create a new promise. If you need to start a promise chain where you don't have a promise, you can simply usePromise.resolve
orPromise.reject
– caasjj Commented Sep 29, 2015 at 21:26 -
function() { resolve(); }
is equivalent toresolve
in this case. – user663031 Commented Sep 30, 2015 at 3:44 - Possible duplicate of stackoverflow./questions/31069453/… – Roamer-1888 Commented Sep 30, 2015 at 13:39
-
1
@caasjj That's true for some promise implementations, but not all of them provide a
.delay()
-type method. ES6 native promises surely don't. – JLRishe Commented Jul 17, 2016 at 6:16
2 Answers
Reset to default 7Does 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.
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.
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 acplished with the promise constructor or by starting with a resolved promise and chaining to it.
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 mon use cases and all are something that can be acplished without a separate deferred object.
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.
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 e natural to just use the promise constructor.
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.
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.
Native Promises don't have all the built-in methods that deferred has out of the box, for example the method to resolve the promise outside the scope of its constructor (very easy to implement with native Promise, though), and the ability to look at the status of a promise (which is hidden from regular JavaScript on native Promises, though it can be inspected in the dev tools).
The main reason to use deferred today would be backwards patibility with code that depends on those extra methods. Hard to give a definitive answer to your question without stepping onto opinion territory.
本文标签: javascriptWhen would someone need to create a deferredStack Overflow
版权声明:本文标题:javascript - When would someone need to create a deferred? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742410265a2469644.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论