确定异步执行何时完成

Determine when async execution is finished

本文关键字:何时完 执行 异步      更新时间:2023-09-26

我必须处理一个entries数组,该数组需要为每个文件条目执行异步任务:getFileuploadResult都是异步任务。我的问题是,如何知道何时使用asyncjs这样的异步库处理数组doc.entries。下面的代码只是我试图实现的一个示例。

var doc = {
    version: '1.7',
    entries: [{
        date: '11/11/10',
        files: [{
            name: 100,
            executable: false
        },
        {
            name: 101,
            executable: false
        }]
    },
    {
        date: '11/12/10',
        files: [{
            name: 200,
            executable: false
        },
        {
            name: 201,
            executable: false
        }]
    },
    {
        date: '11/13/10',
        files: [{
            name: 300,
            executable: false
        }]
    },
    {
        date: '11/14/10',
        files: [{
            name: 400,
            executable: false
        }]
    }]
};
doc.entries.map(function(entry){
    entry.files.map(function(file){
        getFile(file, function(err, result){
            if(err){
                throw Error(err)
            }
            uploadResult(result, function(err, status){
                WriteOnDb(file.name, status, function(err, result){ ... });
            });
        })
    });
});

我如何知道最后一个文件何时存储在数据库中,然后再做其他事情?

谢谢。

最简单的方法是使用promise或更好的可观察性,但也可以通过回调来实现——例如,您可以计算总共有多少任务和完成了多少任务:

var total = doc.entries
  .map(function (entry) {
    return entry.files.length;
  })
  .reduce(function (x, acc) {
    return acc + x
  }, 0);
var finished = 0;
function finishCallback(err) {
  if (err === null) {
    /// all async tasks are finished;
  }
}
doc.entries.map(function (entry) {
  entry.files.map(function (file) {
    getFile(file, function (err, result) {
      if (err) {
        finishCallback(err);
      } else {
        uploadResult(result, function (err, status) {
          WriteOnDb(file.name, status, function (err, result) {
            if (err) {
              finishCallback(err);
            } else {
              finished += 1;
              if (finished === total) finishCallback(null);
            }
          });
        });
      }
    })
  });
});