我试图找出一种方法来等待多个延迟对象并在完成后处理它们,可能就像为延迟对象启动下一组.
我被困了,因为下面的结果不是预期的结果.我期待结果为
allDone resovled values are 1,2,3
Run Code Online (Sandbox Code Playgroud)
实际结果是
allDone resovled values are 1,2
Run Code Online (Sandbox Code Playgroud)
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);
Run Code Online (Sandbox Code Playgroud)
T.J*_*der 10
对于为什么,请看下文.但是你过度复杂了.:-)你给出的最终承诺的回调when给你解决的值作为参数:
$.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`
})
Run Code Online (Sandbox Code Playgroud)
实例:
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);Run Code Online (Sandbox Code Playgroud)
<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>Run Code Online (Sandbox Code Playgroud)
旁注:我假设您故意处理数组.如果您需要等待固定数量的承诺,只需使用更简单的表单即可
$.when(dfd1, dfd2, dfd3).then(function(a, b, c) {
// ...
});
Run Code Online (Sandbox Code Playgroud)
这就是为什么你得到你得到的非常奇怪的结果:jQuery的Deferred/ Promise对象有一个问题,因为它们是混乱的:当你调用done它们时,你不知道你的回调是同步执行还是异步执行.这是一个严重的缺陷,一个真正的Promises/A +实现没有(回调总是异步的).
如果诺言尚未解决,jQuery将异步调用回调.但如果它没有解决,它会同步调用它:
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");
});
Run Code Online (Sandbox Code Playgroud)
所以在你的代码中发生的事情是,在最后一个得到解决的promise()的回调期间触发了整个done回调.由于承诺未标注的解决,直到之后的回调已经完成,当你的代码运行,并得到解决,但仍处于正在解决过程中.所以,你的内在回调被称为同步的和而异步的.因此,在将返回值推送到阵列之前,您将输出结果.whendonedfd3donedfd1dfd2dfd3dfd1dfd2dfd3dfd3
| 归档时间: |
|
| 查看次数: |
4001 次 |
| 最近记录: |