【问题标题】:Trigger a function only after the completion of multiple AJAX requests只有在多个 AJAX 请求完成后才触发一个函数
【发布时间】:2010-08-04 11:54:05
【问题描述】:

我有一个特定的函数我想运行一次,并且只在完成几个 AJAX 请求之后。

我目前的解决方案有点像这样:

function doWork() {
    //This is the function to be run once after all the requests
}

//some tracking/counting variables
var ajaxDoneCounter = 0;
var numOfAjaxRequests = 5;
var workDone = false;

function doWorkTrigger() {
    ajaxDoneCounter++;
    if( !workDone && ajaxDoneCounter >= numOfAjaxRequests ) {
        workDone = true;
        doWork();
    }
}

// ...

//and a number of ajax requests (some hidden within functions, etc)
//they look something like this:
$.ajax({
    url: "http://www.example.com",
    dataType: "json",
    success: function( data ) {
        //load data in to variables, etc
        doWorkTrigger();
    }
});

上面的一个明显缺陷是任何不成功的 AJAX 调用都不会增加ajaxDoneCount,因此doWork() 可能永远不会被调用。我可以在任何$.ajax 中使用error 回调来解决这个问题,所以我不会太担心。

我想知道的是以上是否安全和/或良好的做法?
有没有我错过的技巧,或者其他可能更好的方法?

【问题讨论】:

  • 这是我建议您阅读问题描述时所做的。我不确定“我想不出更好的”是一个合适的“答案”,尽管只是评论。 ;-)

标签: javascript jquery ajax


【解决方案1】:

更新: 从 jQuery 1.5 开始,deferred objects [docs] 提供了更简洁的解决方案。 Have a look at an example here.


我会使用.ajaxComplete(),只要 Ajax 调用完成(成功或错误)就会触发它:

var numOfAjaxRequests = 5;

$(document).ajaxComplete(function() {
    numOfAjaxRequests--;
    if(!numOfAjaxRequests) {
        doWork();

    }
});

那么您不必编辑每个 Ajax 请求。

您甚至可以使用.ajaxSend() 来获得启动 Ajax 请求的通知,而不是对其进行硬编码(但我不确定这是否真的有效,也许您会遇到竞争条件):

var numOfAjaxRequests = 0;

$(document).ajaxSend(function() {
    numOfAjaxRequests++;
});

【讨论】:

  • 啊,很高兴知道 - 但是如果我有两组 Ajax 调用,每组都触发一个单独的函数(我没有,我只是想知道)。这种方法是否允许我将这两组分开,这样两个函数就不会一直等待它完成的所有两个组?
  • @DMA57361:查看文档。 XMLHttpRequest 和 Ajax 调用的选项将传递给回调。您也许可以使用此信息区分呼叫。在文档中是一个示例,仅当 Ajax 调用针对特定 URL 时才会执行回调。
  • 对我来说看起来不错,我想我应该好好阅读那里的文档并进一步调查这两个。谢谢。
【解决方案2】:

我认为你应该使用complete(XMLHttpRequest, textStatus) ajax 事件而不是成功(数据、文本状态、XMLHttpRequest)。

根据jQuery帮助:

complete(XMLHttpRequest, textStatus)

当 请求完成(成功后 错误回调被执行)。这 函数获得两个参数: XMLHttpRequest 对象和一个字符串 描述请求的状态。 这是一个 Ajax 事件。

【讨论】:

    【解决方案3】:

    我对 JavaScript 内部了解不够,但是操作存在危险:

    ajaxDoneCounter++;
    

    不是原子的。如果是这种情况,那么这可能会受到竞争条件的影响。

    【讨论】:

    • 为什么投反对票?如果 ++ 在 JavaScript 中是原子的,请发表评论。发布答案后我的快速研究似乎表明 ECMAScript 没有声明 ++ 是否是原子的。
    • 我也想知道这个-1,我发现this问题,这似乎表明JavaScript仅作为单线程执行,所以大概它只会排队ajax完成后的回调 - 这意味着这个特定问题不相关。不过,如果投反对票的人费心告诉我们...
    • 是的,stackoverflow.com/questions/1663125/is-javascript-multithreaded/… 的评论表明它可能并不总是这样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-12
    • 2020-07-06
    • 2018-12-07
    • 1970-01-01
    • 1970-01-01
    • 2020-12-02
    相关资源
    最近更新 更多