node.jsでpromise(deffered)を使いたかったので現状どうなってるのか簡単に調べた。
まず、本家の
Promiseだけど安定板の
v0.10.30ではまだサポートされていない。仕方ないので
latestの
v0.11.13を使って試してみる。
node.js Promise
サンプルコード。
function promiseA() {
return new Promise(function(onFulfilled, onRejected) {
setTimeout(function() {
console.log('I execute first.');
onFulfilled();
}, 1000);
});
}
function promiseB() {
return new Promise(function(onFulfilled, onRejected) {
setTimeout(function() {
console.log('I execute second.');
onFulfilled();
}, 5000);
});
}
function promiseC() {
return new Promise(function(onFulfilled, onRejected) {
setTimeout(function() {
console.log('I execute third.');
onFulfilled();
}, 5000);
});
}
promiseA().then(promiseB).then(promiseC);
// ダメ. 関数を実行してしまい、promiseBとpromiseCが同時に動く.
//promiseA().then(promiseB()).then(promiseC());
こんな感じか。
最初は
new Promise(..)で取得したオブジェクトを直接
thenに指定してしまい、promiseB, promiseCが同時に実行されてはまる。
お馬鹿な例。
var promiseA = new Promise(function(fulfill, reject) {
setTimeout(function(){ console.log('first.') },1000);
});
var promiseB = new Promise(function(fulfill, reject) {
setTimeout(function(){ console.log('second.') },1000);
});
var promiseC = new Promise(function(fulfill, reject) {
setTimeout(function(){ console.log('third.') },1000);
});
promiseA.then(promiseB).then(promiseC);
newした瞬間に処理実行されちゃってるからな。この
new、地味にこういう誤解を招くと思うんだけど…。
Q
node.jsの現バージョンであるv0.10.30は
Promiseをまだ実装していない。ぐぐったら
Qがデファクトっぽい扱いだったのでこちらで同様の事を試みる。
サンプルコード
var Q = require('q');
function one() {
var deffered = Q.defer();
setTimeout(function() {
console.log('execute one.');
deffered.resolve();
}, 1000);
return deffered.promise;
}
function two() {
var deffered = Q.defer();
setTimeout(function() {
console.log('execute two.');
deffered.resolve();
}, 1000);
return deffered.promise;
}
function three() {
var deffered = Q.defer();
setTimeout(function() {
console.log('execute three.');
deffered.resolve();
}, 1000);
return deffered.promise;
}
one().then(two).then(three).done();
関数内でdefferedを作り、返り値を
deffered.promise、処理完了を
deffered.resolve()で伝えてあげればいいみたい。こっちのほうが凄いしっくりくる。
node.js/Promiseも
thenable使えば似たような感じになりそうだけど、いちいち自前で
newを書くのがちょっと面倒に感じた。