ES6でPromiseが入ってきたので、coをつかってPromiseを体験してみた
バージョン
Node.js 4.1.1
co 4.6.0
プログラム内容
奇数の時はその値を表示表示し、偶数の時はエラーを返す
coを使わない場合
こんな感じになるので, getPromiseが何回も呼ばれるとネストがうざくなる
function getPromise(i) {
return new Promise((resolve, reject) => i % 2 !== 0 ? resolve(i) : reject(new Error(i)))
}
function onSuccess(result) {
console.log('success', result)
}
function onError(e) {
console.log('error', e)
}
getPromise(1)
.then(onSuccess)
.then(() =>
getPromise(2)
.then(onSuccess)
.catch(onError)
)
.catch(onError)
coを使った場合
var co = require('co')
co(function *(){
onSuccess(yield getPromise(1))
onSuccess(yield getPromise(2))
})
.catch(onError)
実行結果
success 1
error [Error: 2]
ざっくりとした使い方
coの中でreturnを呼ぶとthenが呼ばれる
co(function *(){
return yield getPromise(1)
})
.then(onSuccess).catch(onError)
Promiseのrejectが呼ばれた時はエラーが発生するので、try-catchで捕まえる事ができる。ただし、この時はthenのあとに設定しているcatch(onError)は呼ばれない。呼びたいときはthrowする
co(function *(){
try {
let r = yield getPromise(2)
console.log(r)
return r
} catch (e) {
console.log('error catch', e)
}
})
.then(onSuccess)
.catch(onError)
エラーがキャッチされない場合はcatch(onError)が呼ばれる
co(function *(){
let r = yield getPromise(2)
console.log(r)
return r
})
.then(onSuccess)
.catch(onError)
co.wrapは以下の様な感じになるがいまいちいい使い方が思いつかない。
連続して呼び出せないものか。
let p = co.wrap(function *(i){
return yield new Promise((resolve, reject) => {
return i%2 === 0 ? reject(new Error(i)) :resolve(i)
});
});
p(1).then(onSuccess).catch(onError)