将async结果添加到nodejs中的数组

时间:2016-10-24 18:30:41

标签: javascript node.js asynchronous

我对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)。我知道这将是基本的。

2 个答案:

答案 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)