I swear by Q for its simplicity, so I might not have done much research checking out other 'then' implementations. But I've used Q a good deal!
I have a chain of 'then' promises, and I want to resolve a 'batch' of promises in the middle of it and proceed with other operations in sequence; so it's obvious I should use Q.all. But I'm stuck here. Either Q's doing it wrong, or I am.
Here are two hypothetical async operations
var f=function(delay){
return Q.delay(delay).then(function(){
console.log("returning delayed",delay)
return delay
})
}
f2=function(delay){
var defer=Q.defer()
setTimeout(function(){
console.log("returning timedout",delay)
return delay
},delay)
return defer.promise
}
And this is the promise chain
Q('begin')
.then(console.log)
.then(Q.all([100,200,300,400].map(f)))
.then(function(){
console.log("Finally",arguments)
}).done()
And this is the output I wish
begin
returning delayed 100
returning delayed 200
returning delayed 300
returning delayed 400
Finally { '0': undefined }
But this is the output I get
begin
Finally { '0': undefined }
returning delayed 100
returning delayed 200
returning delayed 300
returning delayed 400
I get the same sequence with f2
Now, if I run this
Q.all([100,200,300,400].map(f)).then(function(){
console.log("Finally",arguments)
}).done()
I do get
returning delayed 100
returning delayed 200
returning delayed 300
returning delayed 400
Finally { '0': [ 100, 200, 300, 400 ] }
but using f2
instead of f
gives me
returning timedout 100
returning timedout 200
returning timedout 300
returning timedout 400
It doesn't execute the finally
block.
I get the same outputs with Q.[all/allResolved/allSettled]
So, my queries are,
f
and f2
different since the results by running Q.all().then() with them aren't the same. Q.all
takes an array of promises, but then returns a promise (that is the only resolved when every promise in the array is resolved.
So, I think you need to return the result of Q.all
in order to not immediately call the next then
:
Q('begin')
.then(console.log)
.then(function() {
return Q.all([100,200,300,400].map(f));
})
.then(function(){
console.log("Finally",arguments)
}).done()
Answering the second question, your usage of f2
is incorrect.
When you create a promise using a deferred you must resolve it in order for it to become fulfilled. You can read more about it in How to convert a callback API to promises .
In your case you're creating an empty deferred and returning its promise but you never actually call .resolve
on the deferred. Doing it "more correctly" would be something like:
f2=function(delay){
var defer=Q.defer()
setTimeout(function(){
console.log("returning timedout",delay)
defer.resolve(delay); // note the resolve here vs the return
},delay)
return defer.promise
}
Using Q.delay
works better since it's already promisified. As for other then
implementations Q is hardly bleeding edge right now to say the least :)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.