在承诺链中容纳 Q.all
Accommodating a Q.all in a promise chain
我对 Q 的简单性发誓,所以我可能没有做太多研究来检查其他 'then' 实现。但是我用Q很划算!
我有一个 'then' 的承诺链,我想在它的中间解决一个 'batch' 的承诺,然后依次进行其他操作;所以很明显我应该使用 Q.all。但是我被困在这里了。要么是Q做错了,要么是我做错了。
这里有两个假设的异步操作
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
}
这是承诺链
Q('begin')
.then(console.log)
.then(Q.all([100,200,300,400].map(f)))
.then(function(){
console.log("Finally",arguments)
}).done()
这就是我想要的输出
begin
returning delayed 100
returning delayed 200
returning delayed 300
returning delayed 400
Finally { '0': undefined }
但这是我得到的输出
begin
Finally { '0': undefined }
returning delayed 100
returning delayed 200
returning delayed 300
returning delayed 400
我得到与 f2
相同的序列
现在,如果我 运行 这个
Q.all([100,200,300,400].map(f)).then(function(){
console.log("Finally",arguments)
}).done()
我明白了
returning delayed 100
returning delayed 200
returning delayed 300
returning delayed 400
Finally { '0': [ 100, 200, 300, 400 ] }
但使用 f2
而不是 f
给了我
returning timedout 100
returning timedout 200
returning timedout 300
returning timedout 400
它不执行 finally
块。
我得到与 Q 相同的输出。[all/allResolved/allSettled]
所以,我的问题是,
- 如何通过具体使用 Q.all 实现预期的输出。虽然我有一个解决方法,但它看起来不太好。
f
和 f2
有何不同,因为 运行ning Q.all().then() 与它们的结果不一样。
Q.all
接受一个承诺数组,然后 returns 一个承诺(当数组中的每个承诺都被解决时,这是唯一被解决的.
所以,我认为你需要 return Q.all
的结果,以免立即调用下一个 then
:
Q('begin')
.then(console.log)
.then(function() {
return Q.all([100,200,300,400].map(f));
})
.then(function(){
console.log("Finally",arguments)
}).done()
回答第二个问题,你对f2
的用法不正确。
当您使用 deferred 创建承诺时,您必须解决它才能实现它。您可以在 How to convert a callback API to promises.
中阅读更多相关信息
在您的情况下,您正在创建一个空的延迟并返回其承诺,但您实际上从未对延迟调用 .resolve
。这样做 "more correctly" 会是这样的:
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
}
使用 Q.delay
效果更好,因为它已经被承诺了。至于其他 then
实现,至少可以说,Q 目前还算不上前沿 :)
我对 Q 的简单性发誓,所以我可能没有做太多研究来检查其他 'then' 实现。但是我用Q很划算!
我有一个 'then' 的承诺链,我想在它的中间解决一个 'batch' 的承诺,然后依次进行其他操作;所以很明显我应该使用 Q.all。但是我被困在这里了。要么是Q做错了,要么是我做错了。
这里有两个假设的异步操作
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
}
这是承诺链
Q('begin')
.then(console.log)
.then(Q.all([100,200,300,400].map(f)))
.then(function(){
console.log("Finally",arguments)
}).done()
这就是我想要的输出
begin
returning delayed 100
returning delayed 200
returning delayed 300
returning delayed 400
Finally { '0': undefined }
但这是我得到的输出
begin
Finally { '0': undefined }
returning delayed 100
returning delayed 200
returning delayed 300
returning delayed 400
我得到与 f2
现在,如果我 运行 这个
Q.all([100,200,300,400].map(f)).then(function(){
console.log("Finally",arguments)
}).done()
我明白了
returning delayed 100
returning delayed 200
returning delayed 300
returning delayed 400
Finally { '0': [ 100, 200, 300, 400 ] }
但使用 f2
而不是 f
给了我
returning timedout 100
returning timedout 200
returning timedout 300
returning timedout 400
它不执行 finally
块。
我得到与 Q 相同的输出。[all/allResolved/allSettled]
所以,我的问题是,
- 如何通过具体使用 Q.all 实现预期的输出。虽然我有一个解决方法,但它看起来不太好。
f
和f2
有何不同,因为 运行ning Q.all().then() 与它们的结果不一样。
Q.all
接受一个承诺数组,然后 returns 一个承诺(当数组中的每个承诺都被解决时,这是唯一被解决的.
所以,我认为你需要 return Q.all
的结果,以免立即调用下一个 then
:
Q('begin')
.then(console.log)
.then(function() {
return Q.all([100,200,300,400].map(f));
})
.then(function(){
console.log("Finally",arguments)
}).done()
回答第二个问题,你对f2
的用法不正确。
当您使用 deferred 创建承诺时,您必须解决它才能实现它。您可以在 How to convert a callback API to promises.
中阅读更多相关信息在您的情况下,您正在创建一个空的延迟并返回其承诺,但您实际上从未对延迟调用 .resolve
。这样做 "more correctly" 会是这样的:
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
}
使用 Q.delay
效果更好,因为它已经被承诺了。至于其他 then
实现,至少可以说,Q 目前还算不上前沿 :)