等待多个延迟对象完成并使用已解析的值 [英] Waiting for multiple deferred objects to be finished and use the resolved values
问题描述
我试图想办法等待多个延迟对象并在完成后处理它们,可能就像为延迟对象开始下一组。
I am trying to figure out a way to wait for multiple deferred objects and process them once done, may be like to start next set for deferred objects.
I我被困了,因为以下的结果不是预期的结果。
我期待结果为
I am stuck because the result of the following is not the it is expected to be. I am expecting the result as
allDone resovled values are 1,2,3
实际结果是
allDone resovled values are 1,2
var dfd1 = new $.Deferred();
var dfd2 = new $.Deferred();
var dfd3 = new $.Deferred();
var dfds = [ dfd1, dfd2, dfd3 ];
var resolvedValues = [];
$.when.apply($, dfds).done(function() {
dfds.forEach(function(dfd){
console.log("inloop");
dfd.promise().done(function(value) {
resolvedValues.push(value);
});
});
console.log("allDone resovled values are" + resolvedValues);
})
dfd1.resolve(1);
dfd2.resolve(2);
dfd3.resolve(3);
推荐答案
对于 why ,见下文。但是你过度复杂了。 :-)当你给出解析后的值作为参数时,你给出了从获得的最终承诺的回调:
For the why, see below. But you're overcomplicating it. :-) The callback you give the final promise you get from when
gives you the resolved values as arguments:
$.when.apply($, dfds).done(function(a, b, c) {
// Here, a is 1, b is 2, c is 3
// Or you can access them on `arguments`
})
直播示例:
var dfd1 = new $.Deferred();
var dfd2 = new $.Deferred();
var dfd3 = new $.Deferred();
var dfds = [ dfd1, dfd2, dfd3 ];
var resolvedValues = [];
$.when.apply($, dfds).done(function() {
// Use a trick to turn `arguments` into a real array
var a = Array.prototype.slice.call(arguments);
// Show what we got
snippet.log("allDone: " + a.join(", "));
})
dfd1.resolve(1);
dfd2.resolve(2);
dfd3.resolve(3);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
附注:我假设你正在处理一个数组故意。如果您需要等待固定数量的承诺,只需使用更简单的表格
Side note: I assume you're dealing with an array on purpose. If you have a fixed number of promises you need to wait on, just use the simpler form
$.when(dfd1, dfd2, dfd3).then(function(a, b, c) {
// ...
});
这是为什么你得到你得到的非常奇怪的结果:jQuery的 Deferred
/ Promise
对象有问题,因为它们是 chaotic :当你对它们调用完成
时,你不知道你的回调是否会同时执行 或异步。这是一个严重的缺陷,一个真正的Promises / A +实现没有(回调总是异步)。
Here's why you're getting the very odd result you're getting: jQuery's Deferred
/Promise
objects have a problem in that they are chaotic: When you call done
on them, you don't know whether your callback will be executed synchronously or asynchronously. This is a serious flaw, and one that a true Promises/A+ implementation does not have (the callback is always asynchronous).
jQuery将异步调用回调 如果承诺尚未解决。但如果未已解决,它会将其称为同步:
jQuery will call the callback asynchronously if the promise is not yet resolved. But it will call it synchronously if it isn't resolved:
var d1 = $.Deferred();
d1.done(function() {
console.log("I'm called asynchronously");
});
d1.resolve();
var d2 = $.Deferred();
d2.resolve();
d2.done(function() {
console.log("I'm called synchronously");
});
所以你的代码中发生的是整个已完成
c> c> c> c> c> c> c> c> c> c> c> c>已解决( dfd3
)。由于承诺未在 完成 c>完成回调之后标记已解决,因此当您的代码运行时, dfd1
和 dfd2
已解决,但 dfd3
仍在解决过程中。因此,对于 dfd1
和 dfd2
同步调用内部回调,但异步 dfd3
。因此,在将 dfd3
返回值推送到数组之前,您将输出结果。
So what's happening in your code is that the overall done
callback that when
fires is fired during the done
callback on the last promise that got resolved (dfd3
). Since the promise isn't marked resolved until after the done
callbacks have been completed, when your code runs, dfd1
and dfd2
are resolved but dfd3
is still in the process of being resolved. So your inner callbacks are called synchronously for dfd1
and dfd2
but asynchronously for dfd3
. So you're outputting your result before the dfd3
return value has been pushed onto your array.
这篇关于等待多个延迟对象完成并使用已解析的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!