jQuery Deferred/promise未按预期工作



好的,所以我已经阅读了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.

在编辑中获取代码,有两个问题:

  1. 函数中的计时器在请求解析后启动,但您返回请求所以无论计时器发生什么...它与返回的承诺无关,当时已经解决了。

  2. 您立即调用 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
}

最新更新