Promiseのcatch内でのreturnとthrow
Promiseの(Promiseと言ってもES6 Promisesじゃなくてbluebirdなんだけど)catch内でのreturnとthrowの挙動の違いについて知らなくて試したのでメモ。
環境はnode.js 0.10.33とbluebird 2.3.11です。
var Promise = require('bluebird');
function a() {
return new Promise(function(resolve, reject) {
reject(1);
}).catch(function(err) {
return err;
});
}
a().then(function(data) {
console.log('then');
console.log(data);
});
catchの中でreturnする。
then
1
使う方はthenで値を取れる。
var Promise = require('bluebird');
function a() {
return new Promise(function(resolve, reject) {
reject(1);
}).catch(function(err) {
//return err;
throw err;
});
}
a().then(function(data) {
console.log('then');
console.log(data);
});
catchの中でthrowする。
Possibly unhandled Error: 1
...
catchしてないですよ、とエラーが出力される。これはbluebirdが親切な出力してるのかな。
var Promise = require('bluebird');
function a() {
return new Promise(function(resolve, reject) {
reject(1);
}).catch(function(err) {
//return err;
throw err;
});
}
a().then(function(data) {
console.log('then');
console.log(data);
}).catch(function(err) {
console.error('catch');
console.error(err);
});
使う方でcatchをする。
catch
1
使う方でcatchできた。
まとめ
- catchの中でreturnをするとthenに値を渡せる
- catchの中でthrowをするとcatchに値を渡せる
ということか。今までresolveとrejectにそれぞれ値を渡す方法しかしらなかった。
上記がわかったので場合によってエラーが発生したらデフォルト値を渡す、というようなことが簡潔に書けるようになったと思う。
唯一気がかりなのは、bluebirdを使っているのでES6 Promisesもこういう挙動なのかどうかわからないというところかな……
いつもPromisesで困ったときはJavaScript Promiseの本を読んでるのだけど、今回調べた内容は書いてあるのかな。
読み直してみたらthrowとか使うよりnew Promiseしてrejectを使ったほうがいい、と書いてある。returnとかthrowしたほうが楽だから、と思ってこれを調べたのだけど、それよりもこちらの方が欠点が少ないようなのでちゃんとPromiseを生成して返すようにしよう。