2016-08-14 8 views
0

ファイルからjson配列オブジェクトを処理するのにPromise bluebirdを使用しています。問題は、json配列(リストと呼ばれる)にデータを格納し、最終プロセスでこれを返す場合に発生します。 リストが返された後、または最終プロセスでさえ、リストは空白/未定義です。コードを実行すると、私は常にリストのjsonの追加/プッシュを引き起こすfalseでない1つの値を持っています。JSON配列が未定義で空白が約束Bluebird

この問題を解決できますか?下に私のコードがあります。

ありがとうございます!!!サミュエルの助けを借りて

var Promise = require('bluebird'); 
var join = Promise.join; 
var fs = Promise.promisifyAll(require("fs")); 

fs.readdirAsync(dir).map(function (filename) { 
    return fs.readFileAsync(dir + "/" + filename, "utf8"); 
}).then(function(result){ 
    var list=[]; 

    result.map(function(row, index){ 
     Promise.coroutine(function*() { 
     update(row, index).then(function(value){ 
      if (value!=false){ 
      var trade_update = new updated_Item(row.ID, row.Quantity, row.Price, row.Remark); 
      list.push(trade_update); 
      console.log(JSON.stringify(list));   <-- This works. It gives me data 
      } 
      return list; 
     }) 
     })(); 
    }); 
    console.log('list: ' + JSON.stringify(list));  <-- output: list:[] 
    return list; 
}).finally(function(result){ 
    console.log('Final outcome: '+ ' ' + JSON.stringify(result));  <-- output: Final outcome: undefined 
}) 

私のコードは以下のようになります。

var Promise = require('bluebird'); 
var join = Promise.join; 
var fs = Promise.promisifyAll(require("fs")); 


function updateOrder(done){ 
    fs.readdirAsync(dir).map(function (filename) { 
     return fs.readFileAsync(dir + "/" + filename, "utf8"); 
    }).then(function(result){ 
    var list=[]; 

    result.map(function(row, index){ 
     Promise.coroutine(function*() { 
     update(row, index).then(function(value){ 
      if (value!=false){ 
      var trade_update = new updated_Item(row.ID, row.Quantity, row.Price, row.Remark); 
      list.push(trade_update); 
      done(list);  
      } 
     }) 
     })(); 
    }); 

    //done(list); <--if I put the done callback here, it will give me an empty list. I though once the result.map finished processing all the values give me the end result. 
    } 
} 

updateOrder(function(resultList){ 
    console.log('List' + JSON.stringify(resultList)); 
}) 

このコードは私に今毎回リストが更新(プッシュ)された全体resultListを与えます。

updateOrder関数が終了すると、最後にresultListを受け取ります。

+0

'Promise.coroutine'は非同期なので、' list'は後になるまでの任意の値を取得することはありません。 –

答えて

2

コメントに記載されています。 Promise.coroutineは非同期なので、結果がコードに到達した直後にリターンすることはありません。そして、これは、あなたがコードで得た後者のprintステートメントがlistが未定義であることを示唆している現象をかなり説明しています。あなたは何ができるか

は一緒に、後の処理のためにバック人口のリストを返す、それがその任務を終了したときに起動するためのasync機能のためのパラメータとしてcallback機能を追加し、あなたが機能にそこに着いたコード全体をラップで。

私はあなたのケースの疑似コードを書いていますが、残念ながらIDEでテストできませんでしたが、コンセプトはそこにあり、動作するはずです。

は私の擬似コードを考えてみましょう:

var Promise = require('bluebird'); 
var join = Promise.join; 
var fs = Promise.promisifyAll(require("fs")); 

// Wrap everything you got into a function with a `done` parameter (callback fn) 
function doStuff(done) { 
    fs.readdirAsync(dir).map(function (filename) { 
    return fs.readFileAsync(dir + "/" + filename, "utf8"); 
    }).then(function(result){ 
    var list=[]; 

    result.map(function(row, index){ 
     Promise.coroutine(function*() { 
     update(row, index).then(function(value){ 
      if (value!=false){ 
      var trade_update = new updated_Item(row.ID, row.Quantity, row.Price, row.Remark); 
      list.push(trade_update); 
      } 
      done(list); 
     }) 
     })(); 
    }); 
    }).finally(function(result){ 
    console.log('File read finish, but this doesnt mean I have finished doing everything!'); 
    }) 
} 

// call your function and provide a callback function for the async method to call 
doStuff(function(resultList) { 
    console.log('list: ' + JSON.stringify(resultList)); 
    // Continue processing the list data. 
}); 
+0

@BigSkinnyこの解決策があなたに合っているかどうかを教えてください。 –

+0

こんにちはSamuel Toh、それが動作します。私は今リストを取得します。私はdone(リスト)を入れました。 if関数の内側に追加された値を持たないため、finally関数を削除しました。素晴らしい、あなたの助けに感謝! –

+0

doneパラメータはresult.mapの実行ごとに呼び出されます。 done(list)をコード内の別の場所に移動することによってすべてが完了したらdoneパラメータを呼び出すように変更しようとしますが、移動するとresultListは空です。これがなぜなのか? –

関連する問題