■概要
前回書いた記事のコードを、いただいた以下コメントから改善してみる
$.Deferred() 使うなら .then() 呼ぶよりも そのまま async / await したらいいのでは……?( thenable なので await に対応している。
■async / awaitについて整理
参照①:https://ja.javascript.info/async-await
参照②:https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/async_function
参照③:https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/await
〇 async/await とは
- より快適に promise を利用する特別な構文 (参照①より引用)
〇async
私の理解
-
async function XXX { ~~ }
で、「XXX」という非同期関数を作成する(async関数) - async関数の中で、
await
というキーワードが使える
参照①②で書いたあったこと
-
async function
宣言でAsyncFunction
オブジェクト(= 非同期関数のメソッドを提供する) を作成する。 -
{ ~~ }
の中身では、await
が使える。 - async関数は、常にpromiseを返す(以下例の関数は①と②で同じものを返す)
※以下例は、参照①の引用
例①:戻り値の1は、自動的にpromiseでラップされて例②と同じになる
async function f() {
return 1;
}
例②:例①を明示的に記載
async function f() {
return Promise.resolve(1);
}
〇await
私の理解
-
await
は非同期関数の中で、(返ってきた値を後続で使いたい等)結果が返ってくるまで待ちたい処理に使う - resolveかrejectが返るまで非同期関数の処理を止め、resolveであれば値を受け取って続きの処理が進んでいき、rejectであれば例外を発生させる(try / catch)でキャッチできる
参照①②③で書いたあったこと
-
await
は promise が確定しその結果を返す(履行[resolve]or拒否[reject])まで、JavaScript を待機させる
待機させることで、promiseを返す関数があたかも同期しているかのように動作させる - 履行[resolve]されると、履行されたプロミスの値がawait式の値になる
- 拒否[reject]されると、await式は拒否された値で例外発生する
- 非同期関数内の外で
await
を使おうとした場合、構文エラーになる
書き換えてみる
★resolveとthen
- 1つのthenで3行使っているので、thenの数が増えれば増えるほど行数に影響がありそう
書き換え前
$.Deferred().resolve(5)
.then(function (value) {
return value * 2;
})
.then(function (value) {
console.log(value);
});
- 書き換え前に3行使っていたのが1行にできた
-
(async function() { ~ })();
は無名関数
書き換え後
(async function() {
const result1 = await $.Deferred().resolve(5);
const result2 = await result1 * 2; //書き換え元に合わせて、時間のかかる処理と仮定してawait
console.log(result2);
})();
★上記非同期関数(asynchronousMethod)の利用
※asynchronousMethod
は、書き換え前後とも前回書いた記事と同じ内容
書き換え前
asynchronousMethod()
.then(
function (value) {console.log('成功1:' + value)},
function (value) {console.log('失敗1:' + value)}
});
書き換え後
(async function() {
try {
const value = await asynchronousMethod();
console.log('成功1:' + value);
} catch (value) {
console.log('失敗1:' + value);
}
})();