Javascript 需要尝试阻止和异步调用

Javascript 需要尝试阻止和异步调用,javascript,node.js,asynchronous,callback,Javascript,Node.js,Asynchronous,Callback,我正在尝试运行以下代码,本质上我运行一个api调用来查看在特定时间段内结果存在多少页,在一个循环中运行api调用来获取每个页的返回,然后在这个循环中插入每个结果(使用forEach函数)到mongo数据库中,如果结果的id大于0 但是,我遇到的问题是api调用是异步的,因此当insert函数开始运行时,我收到一个失败消息,表示我试图在其上运行forEach函数的数组(nsprep.responses)未定义 我可以通过任何方式阻止此forEach的运行,直到api调用完成运行。我意识到我可能没有

我正在尝试运行以下代码,本质上我运行一个api调用来查看在特定时间段内结果存在多少页,在一个循环中运行api调用来获取每个页的返回,然后在这个循环中插入每个结果(使用forEach函数)到mongo数据库中,如果结果的id大于0

但是,我遇到的问题是api调用是异步的,因此当insert函数开始运行时,我收到一个失败消息,表示我试图在其上运行forEach函数的数组(nsprep.responses)未定义

我可以通过任何方式阻止此forEach的运行,直到api调用完成运行。我意识到我可能没有正确地构造这些数据,因此重构想法也会很有帮助

function request() {
    uservoiceRequest.get({
        url: "reports/user_satisfaction_responses.json",
        data: {
            page: 1,
            start_date: "2015-01-01T00:00:00-0600",
            end_date: moment().format()
        }
    }, function (err, respData) {
        if (err) return console.log(err)
        console.log(respData.pages)
        for (i = 1; i <= respData.pages; i++) {
            uservoiceRequest.get({
                url: "reports/user_satisfaction_responses.json",
                data: {
                    page: i,
                    start_date: "2015-01-01T00:00:00-0600",
                    end_date: moment().format()
                }
            }, function (err, npsResp) {
                npsResp.responses.forEach(function (e) {
                    if (e.id > 0) {
                        myCollection.insert({
                            created_at: new Date(e.created_at),
                            body: e.body,
                            score: e.score,
                            id: e.id,
                            user: {
                                type: e.user.type
                            }
                        }, function (err, dataInsert) {
                            if (err) return console.log(err);
                        });
                    }
                });
            });
        }
    });
}
函数请求(){
uservoiceRequest.get({
url:“reports/user\u successment\u responses.json”,
数据:{
页码:1,
开始日期:“2015-01-01T00:00:00-0600”,
结束日期:矩()格式()
}
},函数(err,respData){
if(err)返回console.log(err)
console.log(respData.pages)
对于(i=1;i 0){
myCollection.insert({
创建日期:新日期(如创建日期),
body:e.body,
分数:e.score,
id:e.id,
用户:{
类型:e.user.type
}
},函数(错误,数据插入){
if(err)返回console.log(err);
});
}
});
});
}
});
}

如果您想在继续之前完成一组操作,我会将异步调用映射到一组承诺中,然后等待它们。例如,使用下划线和q:

var uservoiceRequestGetPromise = q.bind(uservoiceRequest.get, uservoiceRequest)
uservoiceRequestGetPromise({
            url: "reports/user_satisfaction_responses.json",
            data: {
                page: i,
                start_date: "2015-01-01T00:00:00-0600",
                end_date: moment().format()
            }
}).then(function(npsResp){
   var myCollectionInsertPromise = q.bind(myCollection.insert, myCollection)

   return Q.all(_.map(npsResp.responses, function(e){
        return myCollectionInsertPromise({
                        created_at: new Date(e.created_at),
                        body: e.body,
                        score: e.score,
                        id: e.id,
                        user: {
                            type: e.user.type
                        }
                    }
    }))
}).finally(function(){
   console.log('done')
})
我提供的示例有点草率,但老实说,我试图尽可能多地使用您的代码。将示例的复杂性降低到其根本原则,而不是发布精确的代码,这将使您受益匪浅——这将使人们更容易使用和遵循


也就是说,我认为您可以将一系列NodeJ传统回调转换为promise方法,然后映射到一个数组并收集承诺,最后使用Q。在继续之前也要收集承诺。

使用回调-这就是它们的用途。您可能应该读一点关于promise的内容。这些API是异步的。你不应该阻止他们。如果要在node.js中编写代码,需要学习如何使用多个异步操作编程。避免它没有意义——你应该学会。要使许多异步操作真正按顺序进行,您可以手工编写(当一个操作完成后,启动下一个操作),使用异步库为您排序,或者承诺为您排序。我的首选是蓝鸟承诺库。请准确描述您希望发生的事件顺序。您有一个初始异步调用,然后在该响应中嵌入一个包含异步调用的
for
循环,并在每个响应中嵌入一个包含异步调用的
.forEach()
循环。因此,您可能有很多很多异步调用。确切地说,你希望他们如何排序。请描述理想的操作顺序,而不是代码的工作方式或您是如何尝试的。@jfriend00-很抱歉不够清晰。我想先看看在提供的时间范围内,响应有多少页的数据。然后,对于每个页面,我想获取数据,验证id值是否大于零,然后将其插入mongo数据库。使用bluebird,但方法相同,这很有效,谢谢!