Jquery嵌套延迟等待AJAX响应
有一个函数使用deferred调用另一个函数,其中包含deferred:Jquery嵌套延迟等待AJAX响应,jquery,ajax,deferred,Jquery,Ajax,Deferred,有一个函数使用deferred调用另一个函数,其中包含deferred: var state = true; var construct = function() { var dfd = $.Deferred(); dfd .then(function() { return wakeUp(); }) .then(function() { return makeCoffee();
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函数:$.when的done部分根本不运行,而其他部分在父函数之后执行。有控制台输出:
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请求?我已尝试删除另一个.then语句中的$.when和process。语句没有任何更改,或者返回dfd.promise而不是dfd.resolve,因为它在该函数中阻塞。如何以正确的方式做这件事?接受承诺:
var promise = $.Deferred().resolve().promise();
链可以在单个表达式中形成,如下所示:
var p = promise.then(fnA).then(fnB).then(fnC);
以下是等效的-链由分配形成:
var p;
p = promise.then(fnA);
p = p.then(fnB);
p = p.then(fnC);
以下情况并不等同——fnA、fnB和fnC仅依赖于承诺,而不是相互依赖
promise.then(fnA);
promise.then(fnB);
promise.then(fnC);
问题的关键在于,世界是以非等效模式书写的
使用AJAX完成的console.logWorld取决于最初的承诺(实际上是延迟的承诺)和AJAX
同时,console.logMoon-done和console.logI-m-done在调用者中都只依赖于最初的承诺,并赢得了AJAX延迟消息的竞争
要修复此问题,请通过赋值并返回结果承诺(而不是初始承诺)将conquireTheWorld转换为等效模式
编辑:
全文:
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;
}
有更好的方法可以达到同样的目的,但这是问题代码的正确版本。whoa。该函数可以简化为if状态{return someAjax'http://babeljs.io“.donefunction{console.log'ajax whatever';};}else{console.log'whatever';}方法过度使用。@KevinB在if/else语句之后,我还有一个操作,这样我应该将它复制或分离到另一个函数,不是吗?$.Deferred.resolve不是一个函数-我犯了这个错误。你是说$.Deferred.resolve.promise吗?它也不像预期的那样工作。这是要运行的,但ajax响应仍然在我完成输出后出现。是的,$。延迟。。。。更典型的是,人们倾向于为一个已解决的jQuery承诺编写$。when。但它的行为并不正确,就像我在上面写的那样。有什么东西不等同于模式吗?我在conquireTheWorld中做出了一个承诺,但我仍然迫不及待。你没有按照我说的去做。你需要做作业。