简体   繁体   English

如何保证在函数返回之前保存异步返回值?

[英]How to guarantee that asynchronous return values are saved before function returns?

As I understand it the 100 asyncFunctions in the code below will not be executed until after func has returned true, and at this point the referens to i will not be valid. 据我所知,在func返回true之后,以下代码中的100个asyncFunction将不会执行,此时对i的引用将无效。 Nothing in this code would work as expected I guess. 我想这个代码中的任何内容都不会按预期工作。

Psedo example code: Psedo示例代码:

function func(){
  var needToKnow = []
  for i = 1 to 100 {
    needToKnow[i] = asyncFunction( i )
  }
  //Do some work on needToKnow[i]
  return true
}

What would be the Javascript way to do something like this? 做这样的事情的Javascript方式是什么?

Use callbacks : 使用回调

function func(callback) {
    var needToKnow = [],
        max = 100;

    for (var i = 0; i < max; i++) {
        asyncFunction(i, function (result) {
            needToKnow.push(result);

            if (needToKnow.length == max) { // or something that let you know that its finished
                callback(needToKnow);
            }
        });
    }
}

function asyncFunction(i, callback) {
    setTimeout(function () {
        callback({ index: i });
    }, 1000); // Im an async func!
}

And use it this way: 并以这种方式使用它:

func(function (result) {
    console.log(result);
});

Be careful, don't get in callback hell 小心,不要回调地狱

Here is an example using the Q Promise library: 以下是使用Q Promise库的示例:

function functionThatCouldThrowError(i){
  //It doesn't, but just to give an idea of error propagation.
  return { index: i };
}

function asyncFunction(i) {
  var deferred = Q.defer();
    setTimeout(function () {
      try{
        var data = functionThatCouldThrowError(i);
        deferred.resolve(data);
      } catch (error) {
        deferred.reject({ index: i, error: error });
      }
    }, 1000);
    return deferred.promise;
}

function doAll() {
  var needToKnow = []
  for (var i = 0; i < 100; i++) {
    needToKnow[i] = asyncFunction( i );
  }
  return Q.all(needToKnow);
}

doAll().then(function(arg) {
  //arg contains all 100 elements
  alert("All done");
})

Update: expanded the example to demonstrate how to handle errors. 更新:扩展示例以演示如何处理错误。 Plunker: http://plnkr.co/edit/djWpTKxgvzK2HmkVwvTy?p=preview Plunker: http ://plnkr.co/edit/djWpTKxgvzK2HmkVwvTy?p=preview

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

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