Javascript / Node.js异步循环

时间:2017-05-06 14:48:02

标签: javascript node.js asynchronous

我一般遇到节点异步性质的问题。有人可以帮助我使用这段代码。由于各种原因,我一次只能在我正在使用的数据库中插入1行。实际上,如果我可以添加一个短暂的延迟,每秒只能在数据库中插入1行,那就更好了。

这是我的js代码的一小部分。

console.log('*** Inserting Records ***')
insertPromises = []
_.each(dbRecords, function (item) {
    var insertItem = buildRecord(item)
    insertPromises.push(conn.create(insertItem))
})
Promise.all(insertPromises).then(function (res) {
    _.each(res, function (item) {
        if (!item.success) {
            console.log("### Error ### " + JSON.stringify(res[i].errors))
        }
    })
    console.log('*** Inserted ' + res.length + ' Contacts')
})

我的主要问题是如何在继续循环之前强制循环等待conn.create promise解析?有没有办法将循环减慢到每秒1次迭代?

2 个答案:

答案 0 :(得分:1)

一个简单的解决方案是跟踪“插入计数”,即成功插入记录的当前数量。这将是你的数组指针。使用方法创建每个单独的承诺,并在每次成功响应时将“插入计数”增加1。

let insertCount = 0;

function insertNextRecord() {
    conn.create(buildRecord(dbRecords[insertCount]).then(function(res){
        insertCount += 1;
        insertNextRecord();
    }).catch(function() {
        console.log('Error while inserting record ' + insertCount);
    });
}

insertNextRecord(); 

这未经过测试,我对您未展示的代码做了几个假设。

此示例假定:

  • dbRecords是一个数组
  • conn.create返回承诺对象

要显式添加延迟,您可以在then方法中使用超时,如下所示:

let insertCount = 0;

function insertNextRecord() {
    conn.create(buildRecord(dbRecords[insertCount]).then(function(res){
        insertCount += 1;
        setTimeout(function() {
            insertNextRecord();
        }, 500);
    }).catch(function() {
        console.log('Error while inserting record ' + insertCount);
    });
}

insertNextRecord(); 

我还应该说,你必须这样做是不幸的。处理许多插入时,这将非常慢。

答案 1 :(得分:1)

您可以检查async/await模型。

,而不是使用上面发布的递归代码

使用它的一个例子是:

async function processRecords(dbRecords) {

    for (let item of dbRecords) {
        try {
            let insertItem = buildRecord(item)
            await conn.create(insertItem)
            await delay(1000)
        } catch (e) {
           //handle error...
        }
   }

}

function delay(ms) {
    return new Promise((resolve) => setTimeout(resolve, ms))
}

processRecords(dbRecords)

这是es7代码,您需要babel编译器才能对其进行转换。

如果您发现难以跟上承诺并希望坚持使用类似同步的代码,那么使用这样的东西可能会更好。