在异步函数完成之前,Javascript异步完成了回调

时间:2017-04-13 04:16:13

标签: javascript asynchronous

我一直在尝试诊断这个bug一段时间但是无法弄清楚为什么我的done()函数在我的所有异步函数完成之前执行。我正在使用异步库:

        async.forEach(data.DBInstances, function (dbInstance, fcallback) {
            let dbtype = dbInstance.Engine;
            let logFilename = log[dbtype].log();
            let instanceId = dbInstance.DBInstanceIdentifier;

            if (tagFilter) {
                let arn = dbInstance.DBInstanceArn;
                checkRDSTag(arn, tagFilter, function (err, found) {
                    if (!err) {
                        //tag was found, continue processing and check other filters...
                        if (found) {
                            if (noFilter || (instanceTypes && instanceTypes.indexOf(dbtype))) {
                                //console.log('db type is: ' + dbtype);
                                processOrCreateLog(instanceId, dbType, function (err, data) {
                                    if (!err) {
                                        console.log("Data: " + JSON.stringify(data));
                                        completed.push(data);
                                        fcallback(null);
                                    } else {
                                        cb(err, null);
                                    }
                                });
                            }
                        } else {
                            //tag wasn't found but was specified, don't process anything...
                            console.log("tag specified was not found on instance: " + instanceId);
                        }
                    } else {
                        console.log("Error checking RDS Tag");
                        cb(err, null);
                    }
                });
            }

            //only process filtered types...
            else if (noFilter || (instanceTypes && instanceTypes.indexOf(dbtype))) {
                console.log('db type is: ' + dbtype);
                processOrCreateLog(instanceId, dbtype, fcallback, function (err, data, fcallback) {
                    if (!err) {
                        console.log("Data: " + JSON.stringify(data));
                        completed.push(data);
                        fcallback(null);
                    } else {
                        cb(err, null);
                    }
                });
            }

        }, testme(completed));

我的异步函数正常运行并且每个都正确完成但我的testme(已完成)在我的任何异步函数完成之前立即运行。不知道为什么..

我的testme(已完成)只是:

function testme(completed) {
    console.log("Completed: " + JSON.stringify(completed));
}

注意,我在每个元素上执行的函数本身都有异步函数(checkRDSTag(),processOrCreateLog()等)。我猜它与回调()有关,async期望/跟踪执行不合适或什么?不太确定..

2 个答案:

答案 0 :(得分:0)

仅在最后一项重复

时重新打电话回调
var index=0;
 async.forEach(data.DBInstances, function (dbInstance, fcallback) {
  let dbtype = dbInstance.Engine;
  let logFilename = log[dbtype].log();
  let instanceId = dbInstance.DBInstanceIdentifier;

  if (tagFilter) {
    let arn = dbInstance.DBInstanceArn;
    checkRDSTag(arn, tagFilter, function (err, found) {
      if (!err) {

         //increament index here

         index++;

         //tag was found, continue processing and check other filters...
         if (found) {
          if (noFilter || (instanceTypes && instanceTypes.indexOf(dbtype))) {
                //console.log('db type is: ' + dbtype);
                processOrCreateLog(instanceId, dbType, function (err, data) {
                  if (!err) {
                    console.log("Data: " + JSON.stringify(data));
                    completed.push(data);

                    //check if last item running
                    if(index===data.DBInstances.length){
                      return fcallback(null);  
                    }else{
                      fcallback()
                    }

                  } else {

                    cb(err, null);
                  }
                });
              }
            } else {
                  //tag wasn't found but was specified, don't process anything...
                  console.log("tag specified was not found on instance: " + instanceId);
                }
              } else {
                console.log("Error checking RDS Tag");
                cb(err, null);
              }
            });
  }

            //only process filtered types...
            else if (noFilter || (instanceTypes && instanceTypes.indexOf(dbtype))) {
              console.log('db type is: ' + dbtype);
              processOrCreateLog(instanceId, dbtype, fcallback, function (err, data, fcallback) {
                if (!err) {
                  console.log("Data: " + JSON.stringify(data));


                  completed.push(data);

                  //check if last item running
                  if(index===data.DBInstances.length){
                    return fcallback(null);  
                  }else{
                    fcallback()
                  }

                } else {
                  cb(err, null);
                }
              });
            }

          }, testme(completed));

答案 1 :(得分:0)

我的问题最终出现在我的iteratee中的另一个异步调用(processOrCreateLog())中。我的异步调用中有流控制逻辑没有回调,因此fcallback()从未运行过。

另外澄清一下,async是async node.js库:https://caolan.github.io/async/docs.html#each

只要在iteratee上为每个元素执行带有错误或null的回调,它就可以跟踪所有执行,然后正确地运行你的最终回调。