ホームページ > 記事 > ウェブフロントエンド > Javascript での async/await の仕組みの詳細な説明
関連する推奨事項: 「javascript ビデオ チュートリアル 」
async/await は ES7 の重要な機能の 1 つであり、現在、ES7 で優れていると認識されています。コミュニティの非同期ソリューション。現在、async/await の機能はすでに stage 3 の推奨事項となっています。TC39 の進捗状況をご覧ください。この記事では、async/await の仕組みについて説明します。この記事を読むことで、Promise、ジェネレーター、yield、その他の ES6 に関する関連知識が得られることを願っています。
async/await を詳しく紹介する前に、ES6 の現在の優れた非同期処理メソッドを確認してみましょう。次の例では、データ リクエストは Node.js のリクエスト モジュールを使用し、データ インターフェイスはサンプル デモンストレーションとして Github v3 api document によって提供されるリポジトリ コード リポジトリ詳細 API を使用します。
Node.js の非同期 IO は、高い同時実行性を適切にサポートしますが、「コールバック」を悲惨なものにし、簡単にコールバック地獄を引き起こす可能性があります。名前付き関数の使用などの従来の方法では、ネスト レベルの数を減らし、コードをより明確に見せることができます。ただし、コーディングとデバッグのエクスペリエンスが低下し、名前付き関数の定義を見つけるために Ctrl F を頻繁に使用する必要があるため、IDE ウィンドウが頻繁に上下に移動します。 Promise を使用すると、ネスト レベルの数を大幅に減らすことができます。また、Promise の実装にはステート マシンが使用されており、関数内の解決と拒否によってプロセスが適切に制御され、一連のコード ロジックをシーケンシャル チェーンで実行できます。以下は Promise の使用例です:
const request = require('request'); // 请求的url和header const options = { url: 'https://api.github.com/repos/cpselvis/zhihu-crawler', headers: { 'User-Agent': 'request' } }; // 获取仓库信息 const getRepoData = () => { return new Promise((resolve, reject) => { request(options, (err, res, body) => { if (err) { reject(err); } resolve(body); }); }); }; getRepoData() .then((result) => console.log(result);) .catch((reason) => console.error(reason);); // 此处如果是多个Promise顺序执行的话,如下: // 每个then里面去执行下一个promise // getRepoData() // .then((value2) => {return promise2}) // .then((value3) => {return promise3}) // .then((x) => console.log(x))
ただし、Promise にはまだ欠陥があり、ネストを減らすだけで、ネストを完全に排除することはできません。たとえば、複数の Promise が連続して実行される場合、最初の Promise のロジックが実行された後、then 関数で 2 番目の Promise を実行する必要があります。これにより、ネストの層が作成されます。また、Promise を使用したコードはまだ非同期に見えますが、記述されたコードが同期になれば素晴らしいですね。
ジェネレーターに関しては、馴染みがないわけではありません。 Node.jsのコールバック処理では、私たちがよく使うTJ/Coをpromiseと組み合わせたジェネレーターを使って実装しています。Coはcoroutineの略で、などの言語のコルーチンから借用しています。パイソンとルア。非同期コード ロジックを同期的な方法で作成できるため、コードの読み取りと構成がより明確になり、デバッグが容易になります。
const co = require('co'); const request = require('request'); const options = { url: 'https://api.github.com/repos/cpselvis/zhihu-crawler', headers: { 'User-Agent': 'request' } }; // yield后面是一个生成器 generator const getRepoData = function* () { return new Promise((resolve, reject) => { request(options, (err, res, body) => { if (err) { reject(err); } resolve(body); }); }); }; co(function* () { const result = yield getRepoData; // ... 如果有多个异步流程,可以放在这里,比如 // const r1 = yield getR1; // const r2 = yield getR2; // const r3 = yield getR3; // 每个yield相当于暂停,执行yield之后会等待它后面的generator返回值之后再执行后面其它的yield逻辑。 return result; }).then(function (value) { console.log(value); }, function (err) { console.error(err.stack); });
co はコミュニティでは優れた非同期ソリューションですが、言語標準ではなく、単なる過渡的なソリューションです。 ES7 言語レベルでは、言語レベルの問題を解決するために async/await が提供されます。現在、IE Edge では async / await を直接使用できますが、Chrome と Node.js はまだサポートしていません。幸いなことに、babel はすでに非同期変換をサポートしているため、使用するときに babel を導入するだけで済みます。始める前に、次のパッケージを導入する必要があります。Preset-stage-3 には、必要な async/await コンパイル済みファイルが含まれています。
次のパッケージはブラウザ側と Node.js 側の両方にインストールする必要があります。
$ npm install babel-core --save $ npm install babel-preset-es2015 --save $ npm install babel-preset-stage-3 --save
babel が公式に提供する require フックメソッドを使用することをお勧めします。 require を介して入力すると、次のファイルは必要に応じて Babel によって処理されます。 CommonJs は同期モジュールの依存関係であることがわかっているため、これも実行可能な方法です。このとき、起動用のjsファイルと、実際にプログラムを実行するjsファイルの2つのファイルを記述する必要があります。
実際にプログラムを実行する開始ファイルindex.js
require('babel-core/register'); require('./async.js');
async.js
const request = require('request'); const options = { url: 'https://api.github.com/repos/cpselvis/zhihu-crawler', headers: { 'User-Agent': 'request' } }; const getRepoData = () => { return new Promise((resolve, reject) => { request(options, (err, res, body) => { if (err) { reject(err); } resolve(body); }); }); }; async function asyncFun() { try { const value = await getRepoData(); // ... 和上面的yield类似,如果有多个异步流程,可以放在这里,比如 // const r1 = await getR1(); // const r2 = await getR2(); // const r3 = await getR3(); // 每个await相当于暂停,执行await之后会等待它后面的 //函数(不是generator)返回值之后再执行后面其它的await逻辑。 return value; } catch (err) { console.log(err); } } asyncFun().then(x => console.log(`x: ${x}`)).catch(err => console.error(err));
注:
実際、async/await の使用法は co の使用法と似ています。await と yield はどちらも一時停止を示し、内部のコードが一時停止できることを示すために async または co のレイヤーでラップされています。同期的に処理されます。ただし、async/await の後に続く await 関数は追加の処理を必要とせず、Co がジェネレーターとして記述する必要があります。
プログラミング関連の知識について詳しくは、プログラミング学習をご覧ください。 !
以上がJavascript での async/await の仕組みの詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。