首页 > 解决方案 > Async.forEach 并行运行,但它丢失了原始数组中的排序顺序

问题描述

我正在尝试并行迭代一个集合,并且我正在使用 async.forEach() ,但我也需要维护排序顺序。

async.forEach(books, function (book, bookCallback) {
        findBook(account, userinfo, permission, function (error, foundBook) {
            if (error) {
                bookCallback(error);
            } else if (foundBook) {
                bookCallback(account);
                bookCallback(null);
            } else {
                bookCallback(null);
            }
        });
    }, function (err) {
        if (err) {
            callback(err, null);
        } else {
            callback(null, finaCallback);
        }
    });

我尝试过使用 async.map、async.groupBy,但即使它们也没有维护排序顺序。仅当我尝试 async.eachSeries 时,订单才得以维护,但并未并行运行。

标签: javascriptnode.js

解决方案


在这种情况下您实际上想要async.parallel,但您基本上需要先将输入转换为:

let tasks = [ ...accounts.entries() ].map(([k, account]) =>
  ({ 
    [k]: (callback) => findbook(account, userinfo, permission, callback)
  })
);

async.parallel(tasks, (err,results) => {
    if (err) throw err;          // error handling of some sort
    // reconstruct array order by index position
    results = accounts.map((e,i) => results[i])
})

或者,您可以使用 aPromise和 use包装接受回调的方法Promise.all,它是并行的并且在结果中遵循与使用的输入相同的顺序

Promise.all(
  accounts.map(account => new Promise((resolve,reject) => 
    findbook(account, userinfo, permission, (err, result) => {
      if (err) reject(err);
      resolve(result)
    })
  ))
).then(results => {
  // results have original order
}).catch(err => console.error(err))

推荐阅读