【问题标题】:Use recursion for async loop: How to access push array data?对异步循环使用递归:如何访问推送数组数据?
【发布时间】:2016-04-15 17:04:23
【问题描述】:

这个想法是多次运行地理编码(针对数组)。为了循环一个异步函数,我决定使用递归方式。

var geocoder = require('geocoder')
var geocoded = []

//Example array
var result = [{
  'company_no': 'A',
  'address': 'a'
}, {
  'company_no ': 'B',
  'address': 'b'
}]

function geocodeOneAsync(result, callback) {
  var n = result.length

  function tryNextGeocode(i) {
    if(i >= n) {
      //onfailure("alldownloadfailed")
      return
    }
    var address = result[i].address
    geocoder.geocode(address, function (err, data) {

      geocoded.push(result[i].company_no)
      console.log('data1' + JSON.stringify(
          geocoded)) //Result is ==> data1["A"], data1["B"]
      tryNextGeocode(i + 1)

      //  }
    })
  }
  console.log('data1' + JSON.stringify(geocoded))
  tryNextGeocode(0)
}
geocodeOneAsync(result, function () {
  JSON.stringify('data final ' + geocoded) // result is  empty []. I want to access the final geocoded array?

})

基本上是我如何获得最终值的问题。

【问题讨论】:

  • 顶部的那个对象到底是怎么回事。您问题中的代码格式需要改进。
  • 请使用标准缩进使您的代码可读。 jsbeautifier.org 或您的 IDE 可以提供帮助。
  • 你从来没有在任何地方打电话给callback?只需在基本情况下使用它。
  • 哎呀。对不起..缩进完成..

标签: javascript node.js asynchronous callback


【解决方案1】:

为此,最简单的方法是使用 map 和 Promise 而不是递归。

function geocodeOneAsync(result, callback) {
    // with map you get an array of promises
    var promises = result.map(function (company) {
        return new Promise(function (resolve, reject) {
            var address = company.address;
            geocoder.geocode(address, function (err, data) {
                if(err) {
                    reject(err);
                }
                resolve(company.company_no);
            });
        }).catch(function(error) {
            // you can handle error here if you don't want the first occuring error to abort the operation.
        });
    });

    // then you resolve the promises passing the array of result to the callback.
    Promise.all(promises).then(callback);
}

geocodeOneAsync(result, function (geocodedArray) {
    // here geocoded is ['A','B']
    JSON.stringify(geocodedArray);
});

作为额外的好处,所有异步操作都是并行完成的。

【讨论】:

  • opps..尝试了代码..遇到 TypeError 错误:result.map(...).catch is not a function
  • Oups 错字。捕获必须在新的 Promise 上而不是地图上。
【解决方案2】:

如果这不能回答您的问题,我深表歉意。我相信你需要在递归终止条件下调用你的回调:

if ( i >= n ) {
    callback();
}

完整代码(我自己修改):

var geocoder = require('geocoder');
var geocoded = [];

function geocodeOneAsync(result, callback) {
    var n = result.length;
    function tryNextGeocode(ii) {
        if (ii >= n ) {
            //onfailure("alldownloadfailed")
            callback();
            return;
        }

        var address = result[ii].address
        geocoder.geocode(address, function (err, data) {
            geocoded.push(result[ii].company_no);
            console.log('data1' + JSON.stringify(geocoded)); //Result is ==> data1["A"], data1["B"]_++
            console.log("n=" +n + ",ii=" + ii);
            tryNextGeocode(ii + 1);
        });
    }
    console.log('data1' + JSON.stringify(geocoded));
    tryNextGeocode(0);
};

//Example array
var result = [
    {'company_no': 'A,','address': 'a'},
    {'company_no': 'B', 'address': 'b'}
];
geocodeOneAsync(result, function () {
     console.log(JSON.stringify('data final ' + geocoded)); // result is  empty []. I want to access the final geocoded array?
});

我得到的输出是:

data1[]
data1["A,"]
n=2,ii=0
data1["A,","B"]
n=2,ii=1
"data final A,,B"

希望有帮助!

【讨论】:

  • 感谢 Westandy...看起来 gr8
猜你喜欢
  • 2014-08-19
  • 1970-01-01
  • 2021-11-05
  • 2015-08-23
  • 1970-01-01
  • 2020-01-19
  • 2023-03-23
  • 2017-05-16
  • 1970-01-01
相关资源
最近更新 更多