Promiseとasync&awaitの比較

 
Web Tips.
Booskanium's
Booskanium's Web Tips.

Promiseとasync&awaitの実践的な記述を比較

非同期処理を行う関数の記述例

非同期処理を同期(逐次)処理っぽくす関数記述の事例です。
同期処理っぽくとは、関数内の非同期な処理が終わるまでreturnしない関数という意味です。
これをPromiseとasync&awaitで下記比べてみました。
どちらの書き方が解りやすいかは慣れと用途次第です。

Promiseで書いた方は
・非同期だよという事がはっきりしている
・resolve,rejecをcallbackなアロー関数内でもOKなので便利

async&awaitで書いた方は
・一見簡単そう ・でも例外処理の考慮の記述したい場合はわかしずらい
・Promise化されていないsetTimeoutの様なcalback処理を含む場合はPromiseでラッピングする煩わしさがある

ということでPromise記述は例外処理も考慮するこだわり派に向いている。ただしPromiseという概念の理解が必要。
async&awaitは例外処理等を考慮する必要がなければ平易なコードで書ける。だが、拘り始めると途端に煩雑なコードになる。
まるでXMLHttpRequestとfetchの違いみたいなもの。

なお事例の呼び出し側はThenとcatchとfinallyで非同期っぽく書きました。
慣れると処理の流れを組み立てやすい。

Promiseの事例

3秒後にリターンする非同期関数の事例

function sample(arg) {
	return new Promise((resolve, reject) => {
		if (arg == "ok") {
			setTimeout(() => {
				resolve(`It's OK`);
			}, 3000);
		} else {
			setTimeout(() => {
				reject(`It's NG`);
			}, 3000);
		}
	});
}

sample("ok")
.then((value) => { 
  console.log(`resolve return:${value}`);	//3秒後に戻りはresolveで"OK"が表示される
})
.catch((err) => {
  console.log(`reject return:${err}`);
})
.finally(() => {	//finallyで逐次処理としてつなげる
  sample("ng")
  .then((value) => {
    console.log(`resolve return:${value}`);
  })
  .catch((err) => {
    console.log(`reject return:${err}`);		//3秒後に戻りはrejectで"NG"が表示される
  });
});

asyncとawaitの事例

3秒後にリターンする非同期関数の事例

async function sample(arg) {
	if (arg == "ok") {
		await new Promise(resolve => setTimeout(resolve, 3000)); // 3秒待つ(*1)
		return(`It's OK`);
	} else {
		await new Promise(resolve => setTimeout(resolve, 3000)); // 3秒待つ(*1)
		throw new Error(`It's NG`);		//Promiseのrejectの様な動作になる
	}
}

sample("ok")
.then((value) => { 
  console.log(`OK return:${value}`);	//3秒後に戻りはresolveで"OK"が表示される
})
.catch((err) => {
  console.log(`NG return:${err}`);
})
.finally(() => {	//finallyで逐次処理としてつなげる
  sample("ng")
  .then((value) => { 
    console.log(`OK return:${value}`);
  })
  .catch((err) => {
    console.log(`NG return:${err}`);		//3秒後に戻りはrejectで"NG"が表示される
  });
});
*1 setTimeoutをawaitさせてい場合 Promise化されていないcallback関数をawaitさせる場合は、Promiseでラッピングする。

その他、実践的な事例は気が向いたら追記します。
実践的な記述方法で、もっとスマートにロジックを組み立てる方法があったら教えて下さい。