简体   繁体   English

jQuery JavaScript嵌套异步函数回调

[英]jQuery JavaScript Nested Asynchronous Functions callback

I'm a little confused how to determine when async function called multiple times from another one is finished a call from the last iteration: 我有点困惑如何确定何时从另一个调用多次的异步函数完成了上一次迭代的调用:

function MainAsyncFunction(callback) {
  for (var i = 0; i < 10; i++) {
    SubAsyncFunction(function(success) {
      if (i >= 10 && success) { // THIS IS WRONG?!
        callback(true); // happens too early
      }
    });
  }
};

function SubAsyncFunction(callback) {
  SubSubAsyncFunction(function() {
        callback(true);
  });
}

What I'm doing is calling the Google Distance Matrix service , which has a limitation of 25 destinations, hence I'm having to split my array of destinations to call this service multiple times but I don't understand when it's finished. 我正在做的是调用Google Distance Matrix服务 ,该服务有25个目的地的限制,因此我不得不拆分目的地数组才能多次调用此服务,但我不知道它何时完成。

and in the main bit of code I can tell that the second iteration of the loop in the MainAsyncFunction hasn't yet completed when it does a call back. 并且在代码的主要部分中,我可以说MainAsyncFunction中的循环第二次迭代在执行回调时尚未完成。

I think my problem is I haven't got my head around the order of events when dealing with Async functions in JavaScript... please explain how the subject is normally achieved. 我认为我的问题是在处理JavaScript中的Async函数时,我对事件的顺序一无所知...请说明通常如何实现该主题。

You could use the jQuery Deferred object, which acts as a token representing the status of an async operation. 您可以使用jQuery Deferred对象,该对象充当表示异步操作状态的令牌。

The following is a simplified example: 以下是一个简化的示例:

//set up your sub method so that it returns a Deferred object
function doSomethingAsync() {
    var token = $.Deferred();
    myAsyncMethodThatTakesACallback(function() {
        //resolve the token once the async operation is complete
        token.resolve();
    });
    return token.promise();
};

//then keep a record of the tokens from the main function
function doSomethingAfterAllSubTasks() {
    var tokens = [];
    for (var i=0; i < 100; i++) {
        //store all the returned tokens
        tokens.push(doSomethingAsync());
    }

    $.when.apply($,tokens)
        .then(function() {
            //once ALL the sub operations are completed, this callback will be invoked
            alert("all async calls completed");
        });
};

The following is an updated version of the OP's updated code: 以下是OP更新代码的更新版本:

function MainAsyncFunction(callback) {
  var subFunctionTokens = [];
  for (var i = 0; i < 10; i++) {
    subFunctionTokens.push(SubAsyncFunction());
  }

  $.when.apply($,subFunctionTokens)
  .then(function() {
    callback(true);
  });
};

function SubAsyncFunction() {
  var token = $.Deferred();
  SubSubAsyncFunction(function() {
        token.resolve();
  });
  return token.promise();
};​

Perhaps the ajaxStop() event ? 也许ajaxStop()事件 This is a jQuery event that only fires when all active AJAX requests are completed. 这是一个jQuery事件,仅在所有活动AJAX请求完成时才触发。

The problem is that the value of i is constantly changing in the loop, finally being out of bounds after failing the loop conditional. 问题在于, i的值在循环中不断变化,最终在条件循环失败后最终超出范围。

The easiest way to fix this is: 解决此问题的最简单方法是:

for( i=0; i<5; i++) { // or whatever your loop is
    (function(i) {
        // the value of i is now "anchored" in this block.
    })(i);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM