2016-09-11 13 views
1

Promise.allまたはPromise.map(Bluebird)を使用してPromiseの配列を実行したいと考えていますが、その配列はまだ入力されていますが、配列に値を設定すると結果が返されます。これは、ロード時間が長くかかったり、メモリの制約を引き起こしたりする大きなデータセットを扱う場合に便利です。ポピュレートされている約束配列の結果を待つ

(青い鳥のPromise.mapを使用して)それはデータをロードするためにMongoDBのカーソルを使用して、今日どのように動作するかの例:私はそれが動作したい方法の

// This is a time-intensive operation 
// and requires loading all values into 
// memory before proceeding 
const dataArray = await cursor.toArray(); 

// Start doing work after all objects are in memory 
await Promise.map(dataArray, doSomeWork); 

// done 

例:

const dataArray = []; 
const minItems = N; 
let promiseMap = null; 

// Populate the data array one item at a time 
while (await cursor.hasNext()) { 
    dataArray.push(await cursor.next()); 
    if (!promiseMap && dataArray.length > minItems) { 
     // Start doing work once there is some data to 
     // work with and keep filling the array 
     promiseMap = Promise.map(dataArray, doSomeWork); 
    } 
} 

// Once done filling the array, wait for all promises to resolve 
await promiseMap; 

// done 

これは可能ですか?実行を続行する前に、約束事の静的な配列を持つことは難しいですか?

+1

することはできません単に 'workedOnMap = cursor.map(doSomeWork)。 '、それぞれのアイテムが利用可能になるとすぐに作業できるようにしますか? –

+1

あなたは本質的に(ストリームのような)非同期反復を記述しています。これを可能にする提案があります(非同期関数とジェネレータ関数が混在しています)。しかし、 'all'と' map'は静的なiterablesに対してのみ動作します。 – Bergi

+0

@ Roamer-1888これは私が最初に試したものでしたが、何らかの理由でmongodbドライバのcursor.mapメソッドが期待通りの配列を返さない http://mongodb.github.io/node- mongodb-native/2.1/api/Cursor.html#map – bmajz

答えて

1

the docsから、それは...それは続行する前に終了するのを待って、doSomeWork関数によって返された約束を扱うことができるようになりますeachAsynch

var cursor = someQuery.cursor(); 
cursor.eachAsync(doc => doSomeWork(doc)).then(result => 
    /* after all docs processed */); 
+0

そうですが、問題は、私が約束している最前列の配列を手に入れて解決できないということです。この方法では、記述されているとおりに作業を行うことは可能ですが、すべての作業が完了したことをどのように知っているのですか? – bmajz

+1

カーソルは、約束の配列のようなものです。そして、eachAsynchは、すべての作業が完了したときに満たされるという約束を返します。 – danh

関連する問題