【发布时间】:2017-06-21 07:18:30
【问题描述】:
好的,我已经阅读了 1,000,000 多篇关于 jQuery 延迟和/或承诺的文章,但我仍然遇到了一些问题。
functionOne() {
var deferred = $.Deferred();
var request = $.ajax({
url: 'http://example.com/mypath/etc'
});
request.done(function(data) {
// TODO: I've got stuff here that takes a while.
deferred.resolve();
});
return deferred.promise();
}
functionTwo() {
// Something that depends on the others being finished.
}
$.when(
functionOne(),
anotherLongRunningFunctionWithAjax())
.then(
functionTwo()
);
在“then”开始之前,我需要“when”中的任何函数来完全完成(.ajax done)。然而,promise 立即返回(如预期的那样),但 functionTwo 启动,即使 functionOne 没有调用“done”。
我确信这是对延迟调用和调用链的根本误解。
编辑:
function functionOne() {
console.log('functionOne called');
var request = $.ajax({
url: 'http://example.com/mypath/etc'
});
request.done(function(data) {
console.log('Starting Done.');
setTimeout(function () {
console.log('Done finished.');
}, 5000);
});
console.log('Returning promise.');
return request;
}
function functionTwo() {
console.log('functionTwo called');
}
$.when(functionOne()).then(functionTwo());
在控制台中给我这个:
functionOne called
Returning promise.
functionTwo called (should be called after Done is finished.)
Starting Done.
Done finished.
【问题讨论】:
-
var deferred = $.Deferred();不必要,你已经从 $.ajax 获得了一个。用 .then 将其链接起来。 -
您的逻辑应该可以正常工作,我猜
// TODO:部分实际上有代码并且没有正确延迟 .resolve() 调用。 -
@KevinB 老实说,我先尝试了没有额外的 $.Deferred,但我也无法让它工作。我确定我错过了一些简单的东西。
-
更新后的新代码不会在函数 1 的 setTimeout 完成时延迟函数 2,这是设计使然。对于该功能,您必须使用 .then 而不是 .done 并创建一个新的 Promise 以返回 .then ,它会在 setTimeout 完成时解决。此外,单个 Promise 不需要 $.when,但它也不一定有害。
-
@KevinB 但是无论我使用的是 setTimeout 还是其他东西,至少不会出现“开始完成”吗?我实际上并没有使用 setTimeout,而是加载了一个下拉列表。其实可以完全注释掉setTimeout,“Starting done”还是最后出现的。
标签: javascript jquery