Jquery 嵌套延迟等待 AJAX 响应
Jquery nested deferred wait for AJAX response
有 deferred 的函数在里面调用另一个 deferred 的函数:
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
根本没有运行,其他部分在之后执行parent一个。有控制台输出:
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 语句中处理(没有改变),或者 return dfd.promise()
而不是 dfd.resolve()
(它卡在那个函数中)。如何正确操作?
许下诺言:
var promise = $.Deferred().resolve().promise();
链可以在单个表达式中形成如下:
var p = promise.then(fnA).then(fnB).then(fnC);
下面是等价的——形成一个链"by assigment":
var p;
p = promise.then(fnA);
p = p.then(fnB);
p = p.then(fnC);
以下不等价 - fnA
、fnB
和fnC
只依赖于promise
,不依赖于每个其他.
promise.then(fnA);
promise.then(fnB);
promise.then(fnC);
问题的 conquireTheWorld()
是用 "not equivalent" 格式写的。
console.log("World done with AJAX")
取决于 AJAX.
上的初始承诺(实际上是 Deferred)and
与此同时,console.log("Moon done too")
(和调用者中的 console.log("I'm done")
)都只依赖于最初的承诺,赢得比赛超过AJAX-延迟消息。
要修复,请将 conquireTheWorld()
转换为 "equivalent" 模式,方法是进行赋值并返回结果承诺,而不是初始承诺。
编辑:
完整:
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;
}
有更好的方法可以达到相同的目的,但这是问题中代码的更正版本。
有 deferred 的函数在里面调用另一个 deferred 的函数:
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
根本没有运行,其他部分在之后执行parent一个。有控制台输出:
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 语句中处理(没有改变),或者 return dfd.promise()
而不是 dfd.resolve()
(它卡在那个函数中)。如何正确操作?
许下诺言:
var promise = $.Deferred().resolve().promise();
链可以在单个表达式中形成如下:
var p = promise.then(fnA).then(fnB).then(fnC);
下面是等价的——形成一个链"by assigment":
var p;
p = promise.then(fnA);
p = p.then(fnB);
p = p.then(fnC);
以下不等价 - fnA
、fnB
和fnC
只依赖于promise
,不依赖于每个其他.
promise.then(fnA);
promise.then(fnB);
promise.then(fnC);
问题的 conquireTheWorld()
是用 "not equivalent" 格式写的。
console.log("World done with AJAX")
取决于 AJAX.
与此同时,console.log("Moon done too")
(和调用者中的 console.log("I'm done")
)都只依赖于最初的承诺,赢得比赛超过AJAX-延迟消息。
要修复,请将 conquireTheWorld()
转换为 "equivalent" 模式,方法是进行赋值并返回结果承诺,而不是初始承诺。
编辑:
完整:
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;
}
有更好的方法可以达到相同的目的,但这是问题中代码的更正版本。