簡體   English   中英

等待多個電話的最佳做法

[英]Best Practices to wait for multiple calls

我以這段代碼為起點。

// $ = jQuery
// groupAdata and groupBdata are arrays 

function funcA(elem) {
    for (f = 0; f < groupAdata.length ; f++) {
        // this is an example on how this function calls other functions asynchronously. 
        elem.children('.partyA').each( function() {
            this.innerHTML = "been here" + groupAdata[f];
        });
    }
}

function funcB(elem) {
    // another function that fires more calls
    for (f = 0; f < groupAdata.length ; f++) {
        $.post(url, somedata, function(data) { 
            elem.children('.partyB').each( function() {
                this.innerHTML = "will be there" + groupBdata[f] + data;
            });
        }
    }
}

$(document).ready(function() {

    $('.groupA').each(function () {
        funcA(this);
    });

    $('.groupB').each(function (){
        funcB(this);
    });


});

function endofitall() {
    // call this after all instances of funcA and funcB are done.
}

在運行endofitall() ,我想確保對funcAfuncB所有調用均已完成。

我認為Promises和jQuery.Deferred()是一種很好的/首選的方法,但是無法將我找到的答案映射到此特定方案。 (它是模板工具的一部分,可為多個DOM元素觸發多個dom機械手func[AB] 。)

在每次迭代內調用endofitall()和funcB的endofitall() 保持計數器並在計數器達到表示所有任務已完成的數字后執行實際工作。

function funcA(elem) {
    for (f = 0; f < groupAdata.length ; f++) {
        // these calls are not async
        elem.children('.partyA').each( function() {
            this.innerHTML = "been here" + groupAdata[f];
        });
        endofitall();
    }
}

function funcB(elem) {
    // another function that fires more calls
    for (f = 0; f < groupBdata.length ; f++) {
        $.post(url, somedata, function(data) { 
            elem.children('.partyB').each( function() {
                this.innerHTML = "will be there" + groupBdata[f] + data;
            });
            endofitall();
        }
    }
}

$(document).ready(function() {

    $('.groupA').each(function () {
        funcA(this);
    });

    $('.groupB').each(function (){
        funcB(this);
    });


});

var counter=0;
function endofitall() {
    if(++counter==groupAdata.length + groupBdata.length){
       //do stuff
}

您可以使用$.when()

您的目標應該是:

// call funcA, call funcB
$.when( funcA(), funcB() )
      // when everything is done go on with the callback
     .done(endofitall);

funcA的情況下( 同步功能沒有問題,它將funcA工作)。

對於funcB異步 ),需要考慮一些事項。 如果只是一個ajax調用,則您的代碼應類似於:

// This function returns a promise. 
// When it's fulfilled the callback (in your case '.done(endofitall)') 
// will be called. 
function funcB(somedata){
  return $.post(url, somedata);
}

當您實際發出更多請求時,只有在所有呼叫都已完成后,您才必須返回已解決的Promise。

// an *Asynchronous* function, returns an array of promises
function funcB(elem, groupAdata) {
    var allCalls = [];
    // for each element in the array call the relative async 
    // function. While you're calling it push it to the array.
    groupAdata.forEach(data, function(data){
        allCalls.push( $.post(url, data) );
    });
    // allCalls is now an array of promises.
    // why .apply(undefined)? read here: https://stackoverflow.com/a/14352218/1446845
    return $.when.apply(undefined, allCalls);
}

此時,您可以進行清理:

$.when( funcA(), funcB() ).done(endofitall);

作為一條經驗法則:如果您發出異步請求,請嘗試始終從它們返回一個Promise,這將有助於簡化代碼(如果需要,可以在以后發布一些鏈接),並利用回調的功能。

上面的代碼肯定可以進一步重構(而且,最近幾年我沒有使用過很多jQuery,但是該概念適用於任何Js庫,甚至根本不使用任何庫時),但我希望它將對您有所幫助一個起點。

參考文獻:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM