5

複数のAPI呼び出しを行い、正しい場所で返された結果を取得するのに問題があります。これは私が達成しようとしていることです:ネストされた2つのループ。外側のループは複雑なjsonオブジェクトをループし、いくつかのオブジェクトの値を配列呼び出しボックスに配置します。内側のループはAPIを呼び出し、返された結果をbagという名前の配列に配置します。だから私はデータでいっぱいの箱とバッグを持っています。ループとAPI呼び出しの両方が終了したら、boxとbagの両方のデータにアクセスして、それを使って何かをしたいと思います。実行の同じ時点で両方のアレイにアクセスするための最善の方法がわかりません。これは私がこれまでに持っているものですが、もちろん、すべてのループとAPI呼び出しが終了する前に呼び出されるため、バッグとボックスは空です。

var data = {}//a json object with data;
var bag = [];
var box = [];

async.forEach(data.item, function(item, callback){

    async.forEach(item.name, function(name, callback){

        callApi(item.name, function(obj){

           bag.push(obj);
        });

        callback();

    }

   box.push(item);
   callback();

});


function callApi(name, callback){

    asyncApiCall(url+name, function(err, result){

        callback(result);       
    });

}

//when all loops and api requests are done
//do stuff with contents of box and bag here;
console.log(bag, box);
4

2 に答える 2

4

カウンターを使用して、すべての非同期呼び出しが戻ったことを確認してから、コールバックを呼び出すことができます。例:

function performAsyncOperation(data, onCompletion) {
    var bag = [];
    var box = [];
    var count  = 0;

    async.forEach(data.item, function(item, callback){
        async.forEach(item.name, function(name, callback){
            count += 1;
            callApi(item.name, function(obj){
               bag.push(obj);
               count -= 1;
               if (count == 0) {
                   onCompletion(null, { bag:bag, box:box });
               }
            });
            callback();
        }
       box.push(item);
       callback();
    });
}

count上記のonCompletion重要な部分です。

于 2013-03-02T05:09:46.860 に答える
3

完全なデータセットがあるので、最初に(同期して)名前のリストを1つの単一の配列に収集する必要があります。

次に、の1つのレベルのみを実行しますasync.forEach。2つのレベルでこれを実行しようとすると不要であり、コードがより複雑になります。

あなたが参照してasyncいるものがあなたが使用しnpm install asyncているものである場合、これはあなたが使用できるものを説明するコードの一部です(lodashこれはより簡潔になる傾向があるので、名前のリストを構築するために使用します。

var _ = require("lodash");
var async = require("async");

var data = {
  item: [
    {name: "a"},
    {name: "b"}
  ]
};

var bag = [];

var items = _(_(data.item).collect(function(item) {
  return item.name;
})).value();

async.eachSeries(items, function(name, cb) {
  callApi(name, function(obj) {
    bag.push(obj);
    cb();
  });
}, function done() {
  console.log("bag", bag);
});

function callApi(name, cb) {
  cb(name);
}

そして、出力は次のとおりです。

bag [ 'a', 'b' ]
于 2013-03-02T07:28:11.060 に答える