2016-04-01 7 views
5

iterator()というメソッドを公開するクライアントライブラリを開発しました。このメソッドは、require('promise')ライブラリを使用して作成されたPromiseインスタンスを返します。このインスタンスはイテレータオブジェクトで完成します。 {done: [true|false], key: _, value: _}プロミスイテレータを反復する非再帰的メソッド

iterator()が、それは、その結果の場合には約束を返すために、next()ニーズをいくつかの要素をプリフェッチかもしれません:

このオブジェクトはこのような複雑なオブジェクトで完成された約束を返すnext()と呼ばれる方法が含まれていますリモートコール。

今度は、next()によって返されたPromiseがdone: trueを含むオブジェクトを返すまで、ユーザーはすべての要素を繰り返し処理したいとします。

私は(私はもともとこの answerでこの解決策を見つけた)次の再帰メソッドを使用してこれを達成するために管理してきました

var iterate = client.iterator(); 

iterateTeams.then(function(it) { 

    function loop(promise, fn) { 
    // Simple recursive loop over iterator's next() call 
    return promise.then(fn).then(function (entry) { 
     return !entry.done ? loop(it.next(), fn) : entry; 
    }); 
    } 

    return loop(it.next(), function (entry) { 
    console.log('entry is: ' + entry); 
    return entry; 
    }); 

}); 

問題は、それが構築するために、require('promise')ライブラリを使用して、可能である、です非再帰的な解法?私が非再帰的メソッドに興味を持っている理由は、反復処理するエントリの数が大きすぎると爆発するのを避けることです。

乾杯、 ギャルダー

+0

ジェネレータや観測可能なものを探しているようですね。 – ssube

+0

あなたは再帰を隠していますが、それでも再帰的な解決策をとることができます。 – smnbbrv

+0

ガーダ、「The Collection Kerfuffle」というタイトルのセクションを読んでみてください(http://taoofcode.net/promise-アンチパターン/) –

答えて

2

私は非再帰的方法に興味がある理由は、反復処理項目数が恐れてはいけない

大きすぎると爆破を避けるためです。非同期の「再帰」(時にはpseudo-recursionと呼ばれます)では、呼び出しスタックが大きくならず、末尾再帰によく似ています。あなたは今までにstackoverflow例外を取得しません。

約束ライブラリが合理的に実装されている場合、メモリを増やしてはいけません。詳細はBuilding a promise chain recursively in javascript - memory considerationsを参照してください。

1

新しい構文やライブラリなし - 一般的にありません。

さてあなたはバベルを使用している場合、あなたはES2018を使用することができますが(:P)非同期反復:

for await (const team of iterateTeams) { 
    // do something with team 
} 

read more about it here

そうでない場合、あなたは非同期/のawait構文ES2016で発電機を使用することができます。

for(var it = iterateTeams(); !done; ({done, value}) = await it.next()) { 
    // work with value 
}  

それとも今日利用可能なES2015ジェネレータの構文とbluebirdを介してポンプ付き:

// inside a Promise.corutine 
for(var it = iterateTeams(); !done; ({done, value}) = yield it.next()) { 
    // work with value 
}  
+0

これらのソリューションはありがたくありがとうございます。私はES2015を使用しており、Node.js 0.10(Bluebird Promise.coroutineにはNode.js 0.12が必要です)が必要です。 –

+0

@GalderZamarreñoNodeJS 0.10を使用している場合、どのようにES2015を使用していますか? –

+1

また、答えはまだ再帰やヘルパーメソッドがなく、再帰自体はありません。ES2015の前には不可能です。 –

関連する問題