はじめに
面接中に、async/await は候補者の知識を確認する良い方法です。もちろん、この知識ポイントをどのような角度から説明するかは考えていません。インタビュアーに質問された場合は、自己実行ジェネレーターの構文糖について答えることができます。しかし、私はそれに少し気づいたでしょうか、それとも彼の認識を見たでしょうか?
babel の実装方法
注: ジェネレーターについて知らない場合は、まずジェネレーターを見て、ついでにイテレーターを見てみるのも良いでしょう。
例コード:
async function t() { const x = await getResult(); const y = await getResult2(); return x + y; }
babel 変換コード
"use strict"; function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } function t() { return _t.apply(this, arguments); } function _t() { _t = _asyncToGenerator(function* () { const x = yield getResult(); const y = yield getResult2(); return x + y; }); return _t.apply(this, arguments); }
コードからわかるように、babel
は generator
を変換します。 async
の場合、_asyncToGenerator
と asyncGeneratorStep
の 2 つのステップが使用されます。
_asyncToGenerator
何をしたのか
1. _asyncToGenerator
を呼び出すと、promise
が返されましたが、これはたまたま と一致していました。 async
関数は then
機能に接続できます。
2. 成功したメソッド _next
を定義し、失敗したメソッド _throw
を定義します。 2 つの関数では、asyncGeneratorStep
が呼び出されます。 asyncGeneratorStep
を読むと、これが実際には再帰であることがわかります。
3. _next
を実行します。それが上記の自己実行ジェネレーターです。
asyncGeneratorStep
実行内容
1. Try-catch を実行して、generator
の実行中にエラーをキャプチャします。エラーが報告された場合、async
関数は直接 reject
ステータスに入ります。
2. info
の done
値が true かどうかを確認します。true の場合、イテレータが実行されたことを意味します。値を 解決できます。 ###外出。それ以外の場合は、引き続き
_next を呼び出して値を次の値に渡します。
这里我唯一没有看明白的是`_throw`,这个看代码像是执行不到的。promise.resolve状态值应该是fulfilled。看懂的 可以在评论中和我说一下,感谢。
async/await の利点
新しい構文糖衣が登場するたびに、前世代のソリューションの欠点を補わなければなりません。 例: promise の出現は、コールバック地獄 を回避するためです。これを回避する方法は、呼び出しをチェーンすることです。
async/await は何を解決しますか?
Promise コードと async/await コードの比較
Promise バージョンfunction getData() { getRes().then((res) => { console.log(res); }) }
const getData = async function() { const res = await getRes(); console.log(res); }
Promise を使用する場合、複数の Promise がシリアル化されると、後続の Promise が前の Promise の値を取得することが非常に困難であることがわかります。そして、async はこの問題を正確に解決します。 中間値を取得するための約束の例
const morePromise = () => { return promiseFun1().then((value1) => { return promiseFun2(value1).then((value2) => { return promiseFun3(value1, value2).then((res) => { console.log(res); }) }) }) }
const morePromise = () => { return promiseFun1().then((value1) => { return promiseAll([value1, promiseFun2(value1)]) }).then(([value1, value2]) => { return promiseFun3(value1, value2).then((res) => { console.log(res); }) }) }
const morePromise = async function() { const value1 = await promiseFun1(); const value2 = await promiseFun2(value1); const res = await promiseFun3(value1, valuw2); return res; }
const a = () => { return getResult().then((data) => { if(data.hasMore) { return getMoreRes(data).then((dataMore) => { return dataMore; }) } else { return data; } }) }
const a = async() => { const data = await getResult(); if(data.hasMore) { const dataMore = await getMoreRes(data); return dataMore; } else { return data; } }
const a = async function() { const res = await Promise.all[getRes1(), getRes2()]; return res; }
async/await エラー処理
エラー キャプチャでの async/await を実装するには、promise.all を使用する必要があります。主な側面はトライキャッチです。try-catch
const a = async () => { try{ const res = await Promise.reject(1); } catch(err) { console.log(err); } }
promise のキャッチ
これを行うためにパブリック関数を抽出できます。各 Promise の後に catch 処理が続くため、コードは非常に長くなります。const a = async function() { const res = await Promise.reject(1).catch((err) => { console.log(err); }) }
// 公共函数 function errWrap(promise) { return promise().then((data) => { return [null, data]; }).catch((err) => { return [err, null]; }) }
JS チュートリアル 」
以上がasync/await の詳細の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。