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)