需要尝试阻止和异步调用

时间:2015-07-22 23:23:45

标签: javascript node.js asynchronous callback

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

然而,我遇到的问题是api调用是异步的,所以当插入函数开始运行时,我得到一个失败,说我正在尝试运行forEach函数的数组(nspResp.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);
                        });
                    }
                });
            });
        }
    });
}

1 个答案:

答案 0 :(得分:0)

如果你想在继续之前完成一组操作,我会将我的异步调用映射到promises中,然后等待它们。例如,使用下划线和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')
})

我提供的示例有点草率,但老实说,我试图尽可能多地使用您的代码。您可以真正受益于将示例的复杂性降低到其根本原则,而不是发布您的确切代码 - 人们可以更轻松地使用和关注。

那就是说,我认为你可以将一系列NodeJs传统的回调转换成promise方法,然后映射一个数组并收集promises,最后使用Q.all也可以继续收集你的承诺。