io.jsのES6では標準でPromiseが使えるようになりました。Async.jsで書いてきたコードも、これからはPromiseやGenerator、coなどのコルーチンに移行していきたいです。whileループの書き方がよくわからなかったので、Stack Overflowなどで調べてみました。
リソース
以下のサイトを参考にしました。
- “Infinite” promise chains, a bad thing? #477
- Bluebird
- While loop with promises
- While loop using bluebird promises
- Correct way to write loops for promise.
Bluebirdの無限ループ
Bluebirdは高機能なPromiseのライブラリです。ES6 Native Promiseにはないメソッドや、コルーチンも用意されています。“Infinite” promise chains, a bad thing? #477にwhileループの例がありました。
var Promise = require('bluebird'); |
プログラムはio.jsの3.2.0、Bluebirdは2.9.34実行しました。
$ node -v |
実行結果
1秒間隔で数字がインクリメントされます。無限ループなので適当なところで止めます。
$ node infinite-loop-bluebird.es6 |
ES6 Native Promiseの無限ループ
上記をES6 Native Promiseに書き換えてみます。ES6ネイティブにはBluebirdのdelayや、QのdelayがないのでsetTimeout
で代用します。
Promise.resolve(0).then(function loop(i) { |
実行結果
Bluebirdの結果と同じです。
$ node infinite-loop-native.es6 |
ES6 Native Promiseのwhile ループ
While loop with promisesにあるのは、Qの例ですがES6 Native Promiseに書き換えてみました。
function action(i) { |
実行結果
数字がインクリメントされ、i > 9
がtrueになるとループが停止します。
$ node while-loop-native.es6 |
Bluebirdのwhile ループ
Memory leak trying to create a while loop with promises #502に再帰を使ったシンプルなループの例がありました。
var Promise = require('bluebird'); |
実行結果
$ node just-recursion.es6 |
もうひとつはBluebirdのPromise.coroutineを使う例です。ジェネレーターの中でwhileループを書きます。
var Promise = require('bluebird'); |
実行結果
$ node coroutine-loop.es6 |