javascript - callback用法 - 在繼續之前等待多個異步調用完成




settimeout async (3)

所以,我有一個加載的頁面,並通過jquery.get發出幾個請求,用它們的值填充下拉列表。

$(function() {
    LoadCategories($('#Category'));
    LoadPositions($('#Position'));
    LoadDepartments($('#Department'));

    LoadContact();
};

然後調用LoadContact(); 這是另一個調用,當它返回時,它會填充表單上的所有字段。 問題是通常,下拉列表並非全部填充,因此,它無法將它們設置為正確的值。

我需要做的是,只要其他方法完成並且回調完成執行,LoadContact就會以某種方式執行。

但是,我不想在下拉填充回調的最後放置一堆標誌,然後檢查,並且在調用LoadContact()之前必須進行遞歸的setTimeout調用檢查;

jQuery中有什麼東西可以讓我說,“當所有這些都完成時執行它。”?

更多信息我正在思考這些問題

$().executeAfter(
    function () {   // When these are done
        LoadCategories($('#Category'));
        LoadPositions($('#Position'));
        LoadDepartments($('#Department'));
    },
    LoadContact // Do this
);

...它需要跟踪在執行方法期間發生的ajax調用,並且當它們全部完成時,調用LoadContact;

如果我知道如何攔截在該函數中創建的ajax,我可能會編寫一個jQuery擴展來執行此操作。

我的解決方案

;(function($) {
    $.fn.executeAfter = function(methods, callback) {

        var stack = [];

        var trackAjaxSend = function(event, XMLHttpRequest, ajaxOptions) {
            var url = ajaxOptions.url;

            stack.push(url);
        }

        var trackAjaxComplete = function(event, XMLHttpRequest, ajaxOptions) {
            var url = ajaxOptions.url;

            var index = jQuery.inArray(url, stack);

            if (index >= 0) {
                stack.splice(index, 1);
            }

            if (stack.length == 0) {
                callback();
                $this.unbind("ajaxComplete");
            }
        }

        var $this = $(this);

        $this.ajaxSend(trackAjaxSend)
        $this.ajaxComplete(trackAjaxComplete)

        methods();
        $this.unbind("ajaxSend");
    };
})(jQuery);

這會在調用方法時綁定到ajaxSend事件,並保留一個調用的url列表( 需要更好的唯一id )。 然後它從ajaxSend解除綁定,因此只跟踪我們關心的請求。 它還綁定到ajaxComplete並在返回時從堆棧中刪除項目。 當堆棧達到零時,它將執行我們的回調,並取消綁定ajaxComplete事件。

https://code.i-harness.com


但是,我不想在下拉填充回調的最後放置一堆標誌,然後檢查,並且在調用LoadContact()之前必須進行遞歸的setTimeout調用檢查;
不需要setTimeout。 您只需檢入每個回調,即填充所有三個列表(或者更好地設置計數器,在每個回調中增加它並等待它等於3)然後從回調中調用LoadContact。 對我來說似乎很容易。

ajaxStop方法可能有用,我對它不是很熟悉。



擴展Tom Lianza的答案 , $.when() .when $.when()現在是比使用.ajaxStop()更好的方法。

唯一需要注意的是,您需要確保在返回Deferred object需要等待的異步方法。 幸運的是,jQuery ajax調用默認情況下已經這樣做了。 因此,要從問題中實現場景,需要等待的方法看起來像這樣:

function LoadCategories(argument){
    var deferred = $.ajax({
       // ajax setup
    }).then(function(response){ 
       // optional callback to handle this response 
    });
    return deferred;
}

然後在所有三個ajax調用返回後調用LoadContact()並可選地執行它們自己的單獨回調:

// setting variables to emphasize that the functions must return deferred objects
var deferred1 = LoadCategories($('#Category'));
var deferred2 = LoadPositions($('#Position'));
var deferred3 = LoadDepartments($('#Department'));

$.when(deferred1, deferred2, deferred3).then(LoadContact);




callback