27
22

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

coの使い方メモ

Last updated at Posted at 2015-09-26

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)

Promiserejectが呼ばれた時はエラーが発生するので、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)
27
22
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
22

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?