Jquery延迟没有达到最后。然后

时间:2015-10-03 16:28:18

标签: javascript jquery promise deferred

我有一系列必须执行的功能。除了最后一个,它们都按顺序执行。执行d1,执行d2,执行d3,然后在d4的解析之前执行done函数内的代码。无法弄清楚为什么。任何帮助将不胜感激。

$(document).ready(function() {
    var d1 = functiond1();
    var d2 = functiond2();
    var d3 = functiond3();
    var d4 = functiond4();

    d1.then(d2).then(d3).then(d4).done(function() {

    //Code here does not wait for d4 to end before executing
    //HELP! 

    });
});

function functiond1() {
    var dfd = $.Deferred();

    //Do stuff here
    //Works in sequence

    dfd.resolve();
    return dfd.promise();
}


function functiond2() {

    var dfd = $.Deferred();
    params = jQuery.param({
        'parm1': 1,
        'parm2': 2,
        'parm3': 3
    });


    jQuery.getJSON($.webMethoJSONGet1, params).done(function(data) {

        //Do stuff here
        //Works in sequence

        dfd.resolve();

    });

    return dfd.promise();
}

function functiond3() {
    var dfd = $.Deferred();

    //Do stuff here
    //Works in sequence

    dfd.resolve();
    return dfd.promise();
}

function functiond4() {

    var dfd = $.Deferred();

    params = jQuery.param({
        'parm1': 1,
        'parm2': 2,
        'parm3': 3
    });

    jQuery.getJSON($.webMethoJSONGet2, params).done(function(data) {

        //Do stuff here
        //does not work in sequence

        dfd.resolve();

    });

    return dfd.promise();
}

3 个答案:

答案 0 :(得分:1)

很难说你正在尝试用这些承诺做些什么。您首先调用所有4个函数,然后尝试使用一堆functiond1() .then(functiond2) .then(functiond3) .then(functiond4) .done(function() { /* blah */ }); 回调链接它们。如果你想按顺序将它们连在一起,它应该是这样的:

$.when

如果您只想完成一项结果,可以使用$.when(functiond1(), functiond2(), functiond3(), functiond4()) .then(function(resultd1, resultd2, resultd3, resultd4) { /* blah */ });

done

另一方面,在您的函数中,您创建的promise将在另一个promise的$.getJSON.done()回调中解析,这是不必要的。 done()调用会自行返回一个承诺,因此不需要额外的承诺。只需返回{{1}}返回的承诺。

很抱歉,我没有对jQuery延迟对象进行太多讨论,但它们看起来与标准Promise相似。

答案 1 :(得分:0)

要按顺序运行函数,您需要将引用传递给.then链中的函数,而不是结果来调用这些函数。

e.g。

var d1 = functiond1;   // NB: no ()
...

d1.then(d2).then(d3).then(d4).done(...);    
functiond1().then(functiond2).then(functiond3).then(functiond4).done(...)

问题的最终原因是,立即调用d4将导致其已解决的承诺立即传递到.done,而不管.then的早期部分的状态如何链

您也不应该使用其他承诺包装JSON函数,因为如果AJAX查询失败,$.getJSON已经返回被拒绝的承诺

function functiond4() {
    ...
    return $.getJSON(...);
}

答案 2 :(得分:-2)

我在一个项目上遇到了同样的问题,这个带阵列的解决方案效果很好:



$(document).ready(function() {
    var pr = [];
    var d1 = functiond1();
    var d2 = functiond2();
    var d3 = functiond3();
    var d4 = functiond4();

    function functiond1() {
        var dfd = $.Deferred();
        pr.push(dfd);

        setTimeout(function(){
            $('body').append('1 resolved <br>');
            dfd.resolve();
        }, 2000);
    }


    function functiond2() {
        var dfd = $.Deferred();
        pr.push(dfd);

        params = jQuery.param({
            'parm1': 1,
            'parm2': 2,
            'parm3': 3
        });

        setTimeout(function(){
            $('body').append('2 resolved <br>');            
            dfd.resolve();
        }, 3000);
    }

    function functiond3() {
        var dfd = $.Deferred();
        pr.push(dfd);

        setTimeout(function(){
            $('body').append('3 resolved <br>');
            dfd.resolve();
        }, 1000);
    }

    function functiond4() {
        var dfd = $.Deferred();
        pr.push(dfd);

        params = jQuery.param({
            'parm1': 1,
            'parm2': 2,
            'parm3': 3
        });

        setTimeout(function(){
            $('body').append('4 resolved <br>');
            dfd.resolve();
        }, 50);
    }

    $.when.apply($, pr).then(function() {
        // do something
        $('body').append('proceed with code execution');
    });
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
&#13;
&#13;
&#13;