Node JS中每个的顺序异步操作

Sequential async operations for each in Node JS

我正在进行数据库迁移。这需要查询一个数据库,获取一组记录并执行一组异步操作以将数据插入新数据库。为了保持数据的一致性,我想一次插入一条记录,所以我希望每个操作都按顺序 运行 。我发现执行这些操作的唯一方法是使用递归。

有没有更简洁的方法来做同样的事情?我知道有一个名为 async https://caolan.github.io/async/v3/ 的库,我以前从未尝试过。

我写的递归方法是这样的:

const insertItem = async (data) => {
    let item = data[0];

    if (!item) {
        //I am done return
        return;
    }

    try {
        //Do multiple await calls to insert record into new database
    } catch (e) {
        //Recover from error (DB rollbacks, etc)
    } finally {
        //Remove inserted or failed item from collection.
        data.shift();
        await insertItem(data);
    }
};

//Query original database
getInfo().then((data) => insertItem(data));

您可以使用同步循环for...of它将等待 HTTP 响应。

const dataArr = ['data1', 'data2', 'data3'];

async function processItems(arr){
  for(const el of arr) {
    const response = await insertData(el);    
    // add some code here to process the response.
  }
};

processItems(dataArr);

发布的代码通过使用 data.shift 在调用递归处理所有内容的单个函数之前改变参数数组,实现了对从第一个数据库检索的数据集合(数组)的迭代。

要清理它,通过将数据处理功能分成两部分来删除 shift 和递归调用:

  • 一个函数来遍历从第一个数据库检索到的数据,
  • 根据需要在第二个数据库中插入记录的第二个函数。

这消除了对 .finally 子句的需要,使代码结构看起来更像

async function insertData(data) {
    for( let index = 0 ; index < data.length; ++index) {
        await insertItem( data[index]);
    }
}

async function insertItem( data) {
    try {
        //Do multiple await calls to insert record into new database
    } catch (e) {
        //Recover from error (DB rollbacks, etc)
        // throwing an error here aborts the caller, insertData()
    }
}

getInfo().then( insertData).catch( /*... handle fatal error ...*/);

根据偏好的风格,insertItem 可以声明为 insertData 中的嵌套函数以保持其整洁,并且 insertData 可以写成 insertData 的匿名函数参数=17=] 在 getInfo().

之后调用

当然,可以通过其他方式顺序执行异步操作,但在 async 函数中使用 await 可能是最简单的编码方法。