Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/429.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在Nodejs中使用承诺进行同步http调用_Javascript_Node.js_Promise_Q - Fatal编程技术网

Javascript 如何在Nodejs中使用承诺进行同步http调用

Javascript 如何在Nodejs中使用承诺进行同步http调用,javascript,node.js,promise,q,Javascript,Node.js,Promise,Q,我想使用Q Promissions同步进行http调用,我有100名学生,我需要他们每个人从另一个平台获取一些数据,并通过Q Promissions进行尝试,但这似乎不是同步进行的 如何确保在解析完响应并插入mongodb后,不会再进行另一个调用: 到目前为止,我的代码如下所示: var startDate = new Date("February 20, 2016 00:00:00"); //Start from February var from = new Date(startDate)

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

如何确保在解析完响应并插入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调用何时完成,插入何时完成…

我将放弃您当前的方法,使用npm模块请求承诺。

它很受欢迎,也很成熟

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个请求,工作就可以完成。

如果您希望处理一个又一个学生,请使用
每个系列
,而不是
每个
,以及
回调
,这是
迭代对象的第二个参数。调用
callback
当处理结束时,我不熟悉回调、承诺,我该怎么做?我应该在哪里添加它?@dimafitskin我更新了我的代码,你的意思是这样,添加回调吗?我看到了这个库,它看起来很棒,但我不知道如何使我的代码与此配合工作。。我不知道如何将其转换为某种迭代:s,你能给我一个这样的示例,然后我可以尝试…好的,给我一个3个url的示例,这样我可以看到它们在迭代中的相似之处。url不重要,你可以编写任何url,我只想看看你如何将其转换为foreach或smth。。。很抱歉,我下载了一些很大的东西,我的机器速度很慢-我没有时间做你想做的事情,但我建议你看看或者重新考虑一下,我会花一些时间来做这个-我会做一个plunkr,并在制作完成后给你发一个链接:)