如何在与nodejs的for循环中使用异步函数?

时间:2018-01-22 15:06:50

标签: javascript node.js for-loop asynchronous

我正在使用Nodejs构建一个Web scraper,并且我使用了很多我编写的异步函数。我想使用不同的页面ID运行一系列函数,但是循环似乎没有正常工作。我也尝试使用计数器变量,但它没有产生所需的结果..请在下面找到我的代码:

var pageInformation = [
['page1','id111'],
['page2','id222'],
['page3','id333']];

var reqCounter = 0;

for(page in pageInformation){
    var pageName = pageInformation[reqCounter][0];
    var pageId = pageInformation[reqCounter][1]
    getPosts(pageId,function(err,idArray){
        if(!err){
            getMoreData(idArray, function(data,err){
                if(!err){
                    populateDatabase(data, function(err,success){
                        if(!err){
                        reqCounter++;
                            console.log('Loop for ' + pageName + 'has finished');//prints out page1 three times 
                        }
                    })
                }
            })
        }
    })    
}

会发生什么事情是console.log()打印出page1三次,并且数据库仅使用第一页数据填充。关于如何为pagesInformation数组中的每个页面运行此代码链的任何想法?

1 个答案:

答案 0 :(得分:1)

您的for循环同步运行,而reqCounter仅在每个异步调用完成时递增。这意味着reqCounter在每次迭代中仍然是0

此外,使用var声明的变量不是块作用域,而是作用于当前函数。这意味着pageNamepageId将在每次迭代中重新分配,而不是每次迭代都有自己的变量版本。

后一个问题可以通过用letconst声明这些变量来解决,因为这会使它们成为块范围,即每次迭代都有自己的版本。由于您从未重新分配它们,const是合适的。

对于第一个问题,我不知道为什么你首先需要reqCounter。只需使用迭代器变量page

最后,在数组上使用for...in循环是一个坏主意,因为这很容易导致错误和意外行为。您应该使用for...offorEach()代替。

所以,我的解决方案是改变这三行:

for(page in pageInformation){
    var pageName = pageInformation[reqCounter][0];
    var pageId = pageInformation[reqCounter][1]

进入这个:

for (const page of pageInformation) {
    const pageName = page[0];
    const pageId = page[1];