好的,所以我已经阅读了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()
);
我需要"何时"中的任何函数才能在"然后"开始之前完全完成(.ajax 完成(。但是,承诺会立即返回(如预期的那样(,但 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.
在编辑中获取代码,有两个问题:
-
函数中的计时器在请求解析后启动,但您返回请求。所以无论计时器发生什么...它与返回的承诺无关,当时已经解决了。
-
您立即调用 functionTwo,而不是传递 $.when 承诺回调的函数引用
这是工作代码:
function functionOne() {
console.log('functionOne called');
console.log('Returning promise.');
return $.ajax({
url: 'https://jsonplaceholder.typicode.com/posts/1'
}).then(function(data) {
console.log('Starting Done.');
var dfd = $.Deferred();
setTimeout(function () {
console.log('Done finished.');
dfd.resolve(data); // indicate when you are done
}, 2000); // 2 seconds will do ;-)
return dfd.promise(); // you need to return a promise again
});
}
function functionTwo() {
console.log('functionTwo called');
}
// don't call functionTwo immediately, leave that to the promise to do:
$.when(functionOne()).then(functionTwo);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
您正在使用反模式,因为$.ajax
本身返回了一个承诺
只是做
functionOne() {
var request = $.ajax({
url: 'http://example.com/mypath/etc'
});
request.done(function(data) {
// TODO: I've got stuff here that takes a while.
});
return request
}