2010-08-04 190 views
6

我有一个特定的函数,我想运行一次,并且只在完成几个AJAX请求之后。只有在多个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调用不成功也不会增加ajaxDoneCountdoWork()可能永远不会被调用。我可以在任何$.ajax的内部使用error回调来解决这个问题,这样就不用担心太多。

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

+1

它是什么,我会建议你从阅读问题描述做。我不确定“我想不出任何更好的东西”是一个合适的“答案”,尽管如此只是评论而已。 ;-) – Chris 2010-08-04 11:58:17

回答

6

更新:由于jQuery 1.5,deferred objects[docs]提供了一个更干净的解决方案。 Have a look at an example here

var numOfAjaxRequests = 5; 

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

    } 
}); 

然后,你不必编辑每一个Ajax请求:


我会用.ajaxComplete(),每当一个Ajax调用完成(成功或错误)将被触发。

你甚至可以使用.ajaxSend()得到通知开始Ajax请求,而不是硬编码的(但我不知道这是否真的有效,也许你会遇到竞争条件):

var numOfAjaxRequests = 0; 

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

啊,很高兴知道 - 但是如果我有两组Ajax调用,每个触发一个分隔函数(我不知道,我只是想知道)。这种方法是否允许我分开两组,这样两个功能都不会坚持等待它完成的所有组? – DMA57361 2010-08-04 12:01:51

+0

@ DMA57361:查看文档。XMLHttpRequest和Ajax调用的选项将被传递给回调函数。您可能能够将这些电话与这些信息区分开来。在文档中是一个例子,回调只有在Ajax调用是针对特定URL时才会执行。 – 2010-08-04 12:06:10

+0

对我来说看起来很好,我认为我会很好的阅读那里的文档,并进一步调查这两个文档。谢谢。 – DMA57361 2010-08-04 12:31:30

0

我不对JavaScript内部知识不够充分,但存在操作的危险:

ajaxDoneCounter++; 

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

+0

为什么downvote?如果++在JavaScript中是原子的,那就发表一条关于它的评论。发布答案后我的快速研究似乎表明,ECMAScript不声明如果++是原子或不是。 – 2010-08-05 00:11:30

+0

我想知道这个-1以及我发现[this](http://stackoverflow.com/questions/1663125/is-javascript-multithreaded)的问题,这似乎表明JavaScript只是作为一个单线程,所以推测它会在他们完成时将ajax回调排队 - 这意味着这个特定的问题是不相关的。不过,如果谁做了downvote的话,它会很有帮助,因为它已经困扰了*告诉我们...... – DMA57361 2010-08-05 08:15:41

+0

是的,以及http://stackoverflow.com/questions/1663125/is-javascript-multithreaded/1663578#1663578表明它可能并不总是如此。 – 2010-08-06 04:02:24

1

我认为你应该使用complete(XMLHttpRequest, textStatus) ajax事件而不是成功(data,textStatus,XMLHttpRequest)。

据jQuery的帮助:

complete(XMLHttpRequest, textStatus) 

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

相关问题