如何在Nodejs中使用Promises进行同步http调用

时间:2016-04-09 04:46:19

标签: javascript node.js promise q

我想使用Q Promises同步进行http调用,我有100名学生需要他们每个人从另一个平台获取一些数据并且这样做我尝试通过Q Promises但它似乎不是这样的正在同步进行。

一旦完成解析它的响应并插入mongodb,我如何确保没有进行另一个调用:

到目前为止我的代码看起来像这样:

var startDate = new Date("February 20, 2016 00:00:00");  //Start from February
var from = new Date(startDate).getTime() / 1000;
startDate.setDate(startDate.getDate() + 30);
var to = new Date(startDate).getTime() / 1000;

iterateThruAllStudents(from, to);

function iterateThruAllStudents(from, to) {
    Student.find({status: 'student'})
        .populate('user')
        .exec(function (err, students) {
            if (err) {
                throw err;
            }

           async.eachSeries(students, function iteratee(student, callback) {
                    if (student.worksnap.user != null) {
                        var worksnapOptions = {
                            hostname: 'worksnaps.com',
                            path: '/api/projects/' + project_id + '/time_entries.xml?user_ids=' + student.worksnap.user.user_id + '&from_timestamp=' + from + '&to_timestamp=' + to,
                            headers: {
                                'Authorization': 'Basic xxxx='
                            },
                            method: 'GET'
                        };

                        promisedRequest(worksnapOptions)
                            .then(function (response) { //callback invoked on deferred.resolve
                                parser.parseString(response, function (err, results) {
                                    var json_string = JSON.stringify(results.time_entries);
                                    var timeEntries = JSON.parse(json_string);
                                    _.forEach(timeEntries, function (timeEntry) {
                                        _.forEach(timeEntry, function (item) {
                                            saveTimeEntry(item);
                                        });
                                    });
                                });
                                callback();
                            }, function (newsError) { //callback invoked on deferred.reject
                                console.log(newsError);
                            });
                    }
                });

function saveTimeEntry(item) {
    Student.findOne({
            'worksnap.user.user_id': item.user_id[0]
        })
        .populate('user')
        .exec(function (err, student) {
            if (err) {
                throw err;
            }
            student.timeEntries.push(item);
            student.save(function (err) {
                if (err) {
                    console.log(err);
                } else {
                    console.log('item inserted...');
                }
            });

        });
}

function promisedRequest(requestOptions) {
    //create a deferred object from Q
    process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
    var deferred = Q.defer();
    var req = http.request(requestOptions, function (response) {
        //set the response encoding to parse json string
        response.setEncoding('utf8');
        var responseData = '';
        //append data to responseData variable on the 'data' event emission
        response.on('data', function (data) {
            responseData += data;
        });
        //listen to the 'end' event
        response.on('end', function () {
            //resolve the deferred object with the response
            console.log('http call finished');
            deferred.resolve(responseData);
        });
    });

    //listen to the 'error' event
    req.on('error', function (err) {
        //if an error occurs reject the deferred
        deferred.reject(err);
    });
    req.end();
    //we are returning a promise object
    //if we returned the deferred object
    //deferred object reject and resolve could potentially be modified
    //violating the expected behavior of this function
    return deferred.promise;
}

任何人都可以告诉我,我需要做些什么来实现这些目标? 是否也可以让我知道什么时候所有的http调用都已完成并且插件已经完成...

1 个答案:

答案 0 :(得分:2)

我会放弃你当前的方法并使用npm模块请求 - 承诺。 https://www.npmjs.com/package/request-promise

它非常受欢迎且成熟。

rp('http://your/url1').then(function (response1) {
    // response1 access here
    return rp('http://your/url2')
}).then(function (response2) {
    // response2 access here
    return rp('http://your/url3')
}).then(function (response3) {
    // response3 access here
}).catch(function (err) {
});

现在您只需要将此转换为您想要的100个请求的某种迭代,然后就可以完成工作。