Javascript-处理异步函数调用上的竞争条件

Javascript-处理异步函数调用上的竞争条件,javascript,ajax,asynchronous,Javascript,Ajax,Asynchronous,这个周末,我遇到了一个用Javascript处理比赛条件的特殊问题 下面是给我带来问题的代码: function myFunction(requestObj,myArray){ 对于(var i=0;i您只需要使用闭包: function myFunction(requestObj, myArray) { for(var i=0;i<myArray.length;i++) { //AJAX call closed over i (function(

这个周末,我遇到了一个用Javascript处理比赛条件的特殊问题

下面是给我带来问题的代码:

function myFunction(requestObj,myArray){

对于(var i=0;i您只需要使用闭包:

function myFunction(requestObj, myArray) {
    for(var i=0;i<myArray.length;i++) {
        //AJAX call closed over i
        (function(i) { // wrap your call in an anonymous function
          makeAjaxCall(requestObj, function(data) {
            // i is what you think it is
          }
        })(i) // pass i to the anonymous function and invoke immediately
    }
}
function myFunction(requestObj, myArray) {
    for(var i=0;i<myArray.length;i++) {
        (function(idx){
           makeAjaxCall(requestObj, function(data) {
             //idx will be correct value 
           });
        })(i);
    }
}
function myFunction(requestObj,myArray){

对于(var i=0;i您只需要使用闭包:

function myFunction(requestObj, myArray) {
    for(var i=0;i<myArray.length;i++) {
        //AJAX call closed over i
        (function(i) { // wrap your call in an anonymous function
          makeAjaxCall(requestObj, function(data) {
            // i is what you think it is
          }
        })(i) // pass i to the anonymous function and invoke immediately
    }
}
function myFunction(requestObj, myArray) {
    for(var i=0;i<myArray.length;i++) {
        (function(idx){
           makeAjaxCall(requestObj, function(data) {
             //idx will be correct value 
           });
        })(i);
    }
}
function myFunction(requestObj,myArray){

对于(var i=0;i而言,问题在于您传递给ajax调用的回调持久地引用了
i
,而不是其创建时的值的副本

您的方法很好,只是它会等待第二个ajax调用,直到第一个调用完成,然后等待第二个调用在第三个调用完成之前完成,等等。除非您必须这样做(我觉得您没有这样做),否则最好让它们重叠

有两种选择:

  • 使用生成器函数:

    function myFunction(requestObj, myArray) {
        for(var i=0;i<myArray.length;i++) {
            //AJAX call
            makeAjaxCall(requestObj, buildHandler(i));
        }
        function buildHandler(index) {
            return function(data) {
                // Use `index` here
            };
        }
    }
    
    Function#bind
    创建一个函数,当调用该函数时,该函数将使用一个特定的
    值(我们不使用上面的值)和您传递的任何参数
    bind
    -后跟给绑定函数的任何参数来调用原始函数


  • 我更喜欢#1:读起来很清楚,不会创建一堆不必要的函数(而理论上,#2会为每个循环创建两个函数,而不是一个)。问题是,传递给ajax调用的回调持久地引用了
    I
    ,而不是创建时它的值的副本

    您的方法很好,只是它会等待第二个ajax调用,直到第一个调用完成,然后等待第二个调用在第三个调用完成之前完成,等等。除非您必须这样做(我觉得您没有这样做),否则最好让它们重叠

    有两种选择:

  • 使用生成器函数:

    function myFunction(requestObj, myArray) {
        for(var i=0;i<myArray.length;i++) {
            //AJAX call
            makeAjaxCall(requestObj, buildHandler(i));
        }
        function buildHandler(index) {
            return function(data) {
                // Use `index` here
            };
        }
    }
    
    Function#bind
    创建一个函数,当调用该函数时,该函数将使用一个特定的
    值(我们不使用上面的值)和您传递的任何参数
    bind
    -后跟给绑定函数的任何参数来调用原始函数


  • 我更喜欢#1:阅读起来很清楚,不会创建一堆不必要的函数(而在理论上,#2会为每个循环创建两个函数,而不仅仅是一个)。还有两种方法可以做到这一点:使用绑定,使用闭包

    使用:

    function myFunction(requestObj,myArray){
    
    对于(var i=0;i,还有两种方法可以做到这一点:使用bind和闭包

    使用:

    function myFunction(requestObj,myArray){
    对于(var i=0;i