我对Node.js相当新,而且它的生命我似乎无法弄清楚整个回调异步的事情。
我想要实现的是“相对”简单,如果它所有阻塞调用。
1)请求列表
2)遍历元素
3)为新列表创建新元素,其中新元素属性是另一个请求的结果
4)将新元素添加到新列表
细节:
var originalList = [{
provider: "ABC",
loc: [13.37224, 52.53862],
state: 22
}, {
provider: "CDE",
loc: [13.37124, 52.53262],
state: 33
}, {
provider: "EFG",
loc: [13.37214, 52.53662],
state: 44
}];
var newElement;
var newList = [];
var vLat, vLng;
originalList.forEach(function(element, index, array) {
newElement = {
provider: element.provider,
state: element.state
};
vLat = element.loc[1];
vLng = element.loc[0];
async.parallel([
function(callback) {
var location;
googleMapsClient.reverseGeocode({
latlng: [vLat, vLng],
result_type: ['street_address'],
location_type: ['ROOFTOP', 'APPROXIMATE']
}, function(err, response) {
if (!err) {
var result = response.json.results;
location = result[0].formatted_address;
newElement.location = location;
callback();
} else {
callback(err);
}
});
}
], function(err) {
if (err) console.log(err);
newList.push(newElement);
});
});
我省略了第二个异步功能,该功能也会产生Google地图请求,并且应该将该结果添加到newElement。
我真的很难为什么newElement没有获得新属性(newElement.location)。我知道这将是基本的。
答案 0 :(得分:1)
循环也需要异步来控制处理所有项目的流程。使用async.each()或async.eachSeries()(一个接一个地处理列表):
var originalList = [{
provider: "ABC",
loc: [13.37224, 52.53862],
state: 22
}, {
provider: "CDE",
loc: [13.37124, 52.53262],
state: 33
}, {
provider: "EFG",
loc: [13.37214, 52.53662],
state: 44
}];
var newList = [];
async.each(originalList, function (element, eachCb) {
var newElement = {
provider: element.provider,
state: element.state
};
var vLat = element.loc[1];
var vLng = element.loc[0];
async.parallel([
function(callback) {
var location;
googleMapsClient.reverseGeocode({
latlng: [vLat, vLng],
result_type: ['street_address'],
location_type: ['ROOFTOP', 'APPROXIMATE']
}, function(err, response) {
if (!err) {
var result = response.json.results;
location = result[0].formatted_address;
newElement.location = location;
callback();
} else {
callback(err);
}
});
}
], function(err) {
if (err) {
console.log(err);
} else {
newList.push(newElement);
}
eachCb(); // <<<<< call to signal it's done!!
});
}, function (err) {
console.log('finish processing all items in originalList');
});
如果只有1个任务,则不需要async.parallel()
答案 1 :(得分:0)
我认为您的代码应该如下所示
var originalList = [{
provider: "ABC",
loc: [13.37224, 52.53862],
state: 22
}, {
provider: "CDE",
loc: [13.37124, 52.53262],
state: 33
}, {
provider: "EFG",
loc: [13.37214, 52.53662],
state: 44
}];
var newElement;
var newList = [];
var vLat, vLng;
originalList.forEach(function(element, index, array) {
newElement = {
provider: element.provider,
state: element.state
};
vLat = element.loc[1];
vLng = element.loc[0];
async.parallel([
function(callback) {
var location;
googleMapsClient.reverseGeocode({
latlng: [vLat, vLng],
result_type: ['street_address'],
location_type: ['ROOFTOP', 'APPROXIMATE']
}, function(err, response) {
if (!err) {
var result = response.json.results;
location = result[0].formatted_address;
newElement.location = location;
callback(null, 'success');
} else {
callback(err);
}
});
}
], function(err, results) {
if (err) console.log(err);
newList.push(newElement);
});
});
遵循async.parallel API文档,callback()
中的if (!err)
必须为callback(err, results)