Edited at

Node.js にて await を付けて呼び出した関数が例外を投げた場合の挙動を見る

await を付けて呼び出した関数が例外を投げた場合のサンプルコード


概要


  • await をつけて Promise オブジェクトを返す関数を呼び出す

  • Promise オブジェクトを返すと思っていた関数が例外を発生させた場合の挙動を見る


Promise と await と async とは

Promise - JavaScript | MDN


Promise オブジェクトは非同期処理の最終的な完了処理(もしくは失敗)およびその結果の値を表現します。


await - JavaScript | MDN


await 演算子は、async function によって Promise が返されるのを待機するために使用します。

await 式は async function の実行を一時停止し、Promise の解決または拒否を待ちます。解決した後に async function の実行を再開します。再開するときに await 式は解決された Promise にラップされた値を返します。

Promise が拒絶された場合、await 式は理由となった値をスローします。

await 式に続く値が Promise ではなかった場合、解決された Promise に変換されます。


「解決」は resolve のことで、「拒絶」は reject のこと。

async function - JavaScript | MDN


async function 宣言は、 AsyncFunction オブジェクトを返す 非同期関数 を定義します。非同期関数は非同期でイベントループを介して実行され、暗黙的にPromiseを返します。なおコードのシンタックス及び構造は通常の同期関数と非常に似たものになります。



サンプルコード

// Promise オブジェクトを返す or 例外が発生する関数

function foo(value) {
switch (value) {
case 'resolve':
// resolv を呼ぶ Promise を返す
return new Promise(function(resolve, reject) {
resolve({result: 'success'});
});
break;
case 'reject':
// reject を呼ぶ Promise を返す
return new Promise(function(resolve, reject) {
reject({result: 'failure'});
});
break;
case 'except':
// 例外を発生させる
throw new Error('error message');
break;
}
}

async function bar(value) {
try {
const r = await foo(value);
console.log('result: ' + JSON.stringify(r));
} catch (e) {
console.log('exception: ' + JSON.stringify(e));
console.log(e);
}
console.log('');
}

async function main() {
console.log('*** resolve ***');
await bar('resolve');
console.log('*** reject ***');
await bar('reject');
console.log('*** except ***');
await bar('except');
}

main();


実行結果


  • resolve → resolve メソッドに渡した値が戻り値になる

  • reject → reject メソッドに渡した値が例外として投げられる

  • 例外発生 → 呼び出し先の関数内で throw した例外が投げられる

*** resolve ***

result: {"result":"success"}

*** reject ***
exception: {"result":"failure"}
{ result: 'failure' }

*** except ***
exception: {}
Error: error message
at foo (/Users/me/hoge/try-promise.js:18:13)
at bar (/Users/me/hoge/try-promise.js:25:21)
at main (/Users/me/hoge/try-promise.js:40:9)
at process._tickCallback (internal/process/next_tick.js:68:7)
at Function.Module.runMain (internal/modules/cjs/loader.js:757:11)
at startup (internal/bootstrap/node.js:283:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:622:3)


今回の環境

macOS Mojave + Node.js v10.15.3

$ node --version

v10.15.3

$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.14.4
BuildVersion: 18E226