我需要迭代一个数组,对于我通过调用HTTP call
来应用操作的每个项目。
难点在于我需要syncronize
这个过程以便在循环之后调用回调(在HTTP call
执行所有操作之后包含数组)。
让我们考虑一下这个简短的例子:
function customName(name, callback) {
var option = {
host:'changename.com',
path: '/'+name,
headers: { 'Content-Type': 'application/json' },
port: 80,
method:'POST'
};
var req = http.request(option, function(res) {
var output = "";
res.on('data', function (chunk) {
output += chunk;
});
res.on('end', function() {
var obj = JSON.parse(output);
callback(obj.res);
});
});
req.on('error', function(e) {
console.error(e.message);
});
req.end();
}
function changeNames(OldNames, callback) {
var Res = [];
for (name in OldNames) {
customName(OldNames[name], function(new_name) { Res.push(new_name); });
});
callback(Res);
}
var Names = ['toto', 'tata', 'titi'];
changeNames(Names, function(Names) {
//...
});
此处循环在第一个HTTP call
之前结束,因此Res array
为空。
我们如何同步此执行?
我知道在nodejs中同步治疗并不是很好。你认为与客户端逐个传递名称而不构建数组更好吗?
答案 0 :(得分:2)
您可以使用async.map
。你传递了你的名字列表,它会为每个名字运行getOriginalName
函数(我认为你错误地称之为customName
)并收集结果,最后它将调用一个函数一系列结果:
var http = require('http');
var async = require('async');
function getOriginalName(name, callback) {
var option = {
host:'changename.com',
path: '/'+name,
headers: { 'Content-Type': 'application/json' },
port: 80,
method:'POST'
};
var req = http.request(option, function(res) {
var output = "";
res.on('data', function (chunk) {
output += chunk;
});
res.on('end', function() {
var obj = JSON.parse(output);
callback(null, obj.res);
});
});
req.on('error', function(e) {
callback(e);
});
req.end();
}
function changeNames(OldNames, callback) {
async.map(OldNames, getOriginalName, callback);
}
var Names = ['toto', 'tata', 'titi'];
changeNames(Names, function(err, NewNames) {
console.log('N', NewNames);
});