如何在NodeJS中重复和同步调用远程API?

时间:2015-07-20 14:45:39

标签: javascript node.js asynchronous

我有一个电子邮件列表,想了解有关电子邮件用户的更多信息。所以我为每封电子邮件重复调用一个远程API。我面临的问题是,由于http模块在​​NodeJS中是异步的,我无法在控件进入其他地方之前捕获此信息。

这是我的远程API调用

var callApi = function(email) {
    var request = http.get(apiUrl + '"' + email + '"', function (response) { 
        var buffer = '', jsonData;

        response.on('data', function (chunk) {
            buffer += chunk;
        });

        response.on('end', function (err) {
            jsonData = JSON.parse(buffer);
            jsonData = jsonData[0];
            userData[email].username = jsonData.name;
            userData[email].org = jsonData['org-title'];

            console.log(userData[email].username + ": " + userData[email].org);
        }); 
    });
};

我以下列方式调用此函数

for(var email in userData) {
    callFaceApi(email);
}
storeDataJson(filePath, userData);
在请求返回之前调用

storeDataJson,并且我写入的文件始终为空。

2 个答案:

答案 0 :(得分:1)

在vanilla javascript中你可以创建一个"队列"这样的电子邮件:

var queue = [];
for (var email in userData)
    queue.push(email);
dequeue();

var dequeue = function() {
    if (!queue.length)
        return storeDataJson(filePath, userData);

    var email = queue.shift();
    callApi(email, dequeue);
}

var callApi = function(email, callback) {
    ...
    response.on('end', function (err) {
        ...
        callback();
    });
}

或者您可以使用具有大量功能的async模块来完成此类任务(例如parallelseries

答案 1 :(得分:0)

您对每个电话的回复都在此处理:

response.on('end', function (err) {

所以你可以在那里做一些计数。

您应该处理对

的调用
storeDataJson(filePath, userData);

在该函数中,还有一些额外的逻辑。

您需要添加一些逻辑来检查它们是否已经全部处理完毕,并且仅在最后一个函数处于运行状态时运行该函数。

也许这更容易:创建一个名为emailDataArrived的函数,并在响应结束时调用该函数。 将emailDataArrived放在可以访问userData的位置,只需使用计数器来计算答案数。只要它匹配userData的长度,就写下你的文件。