具有延迟的函数调用另一个具有延迟内部函数的函数:
var state = true;
var construct = function() {
var dfd = $.Deferred();
dfd
.then(function() {
return wakeUp();
})
.then(function() {
return makeCoffee();
})
.then(function() {
return conquireTheWorld();
})
.then(function() {
console.log("I'm done");
});
dfd.resolve();
}
var wakeUp = function() {console.log('Woke up');}
var makeCoffee = function() {console.log('Made some coffee');}
var conquireTheWorld = function() {
var dfd = $.Deferred();
if (state) {
dfd.then(function() {
return $.when(someAjax('http://babeljs.io')).done(function() {console.log("World done with AJAX");})
});
} else {
dfd.then(function() {
console.log("World done in a simple way");
});
}
dfd
.then(function() {
console.log("Moon done too");
});
return dfd.resolve();
}
var someAjax = function(url) {
return $.ajax({
type: 'GET',
url: url
});
}
不幸的是,在这种情况下它会卡在conquireTheWorld
函数中:.done
部分$.when
根本没有运行,而其他部分则在父项之后执行。有控制台输出:
Woke up
Made some coffee
Moon done too //executed before ajax request complete
I'm done //executed before conquerTheWorld function ajax
World done with AJAX
如何等待ajax请求?我尝试删除$ .when并在另一个.then语句中处理(没有更改),或者返回dfd.promise()
而不是dfd.resolve()
(它停留在该函数中)。如何正确地做到这一点?
答案 0 :(得分:1)
承诺:
var p = promise.then(fnA).then(fnB).then(fnC);
链可以在单个表达式中形成如下:
var p;
p = promise.then(fnA);
p = p.then(fnB);
p = p.then(fnC);
以下是等价物 - 形成一条链" by assigment" :
fnA
以下不等效 - fnB
,fnC
和promise
仅依赖于promise.then(fnA);
promise.then(fnB);
promise.then(fnC);
,而不是彼此依赖。
conquireTheWorld()
问题的console.log("World done with AJAX")
是用"不等同的"写的。图案。
console.log("Moon done too")
取决于AJAX上的初始承诺(实际上是延迟的)和。
与此同时,调用者中的console.log("I'm done")
(和conquireTheWorld()
)都只依赖于初始承诺,并且通过AJAX延迟消息赢得竞赛。
要修复,请将var conquireTheWorld = function() {
var promise = $.when(); // shorthand way to create a resolved jQuery promise.
if (state) {
promise = promise.then(function() {
return someAjax('http://babeljs.io').then(function() { console.log("World done with AJAX"); });
});
} else {
promise = promise.then(function() {
console.log("World done in a simple way");
});
}
promise = promise.then(function() {
console.log("Moon done too");
});
return promise;
}
转换为"等效的"模式通过分配和返回结果承诺,而不是最初的承诺。
编辑:
完整:
{{1}}
有更好的方法可以实现相同目的,但这是问题中代码的更正版本。