Javascriptのジェネレータ関数とyieldキーワード

高洛峰
リリース: 2016-11-15 14:48:45
オリジナル
1262 人が閲覧しました

注文

Javascript で誰もが最も議論するのは、非同期プログラミングの操作と、コールバックの多重ネストを回避する方法です。非同期操作のコールバックが多数ネストされると、コードが肥大化するだけでなく、エラーも発生しやすくなります。有名な Promise 社など、さまざまな非同期プログラミング ソリューションが常に提案されています。今日説明するジェネレーターとyieldは非同期プログラミングに関連しており、非同期プログラミングの同期に役立ちます。

ジェネレーターの概要

ジェネレーターは、関数と関数名の間に余分な * があることを除いて、フォーム上の関数に似ています。 yield キーワードはジェネレーター内で使用する必要があります。例:

function * gen(){ var result1 = yield 'hello'; var result2 = yield 'world'; return result1 + result2; }
ログイン後にコピー

ジェネレーター関数が呼び出されると、関数内のコードは実行されませんが、next メソッドを含むトラバーサーが返されます。次のメソッドが実行されるたびに、Generator 関数本体は実行を開始し、yield ステートメントに到達してステートメントを実行し、ここで一時停止します。使用法は次のとおりです。

var g = gen(); g.next(1); //{value : 'hello', done : false} g.next(2); //{value : 'world', done : false} g.next(); //{value : 3, done: true} g.next(); //{value : undefined, done: true}
ログイン後にコピー

next メソッドを呼び出すと、オブジェクトが返されます。このオブジェクトには、value と Done という 2 つの属性が含まれています。Value は、現在の yield ステートメントの値です。 Done は、ジェネレーター関数本体が実行されたかどうかを示します。次のメソッドはパラメーターも受け入れます。このパラメーターは、yield ステートメントの戻り値として使用され、後続のプログラムで使用できます。プログラムの実行が終了するか、return ステートメントに遭遇すると、value は関数本体の戻り値となり、done は true になります。この時点で、次のメソッドが再度実行されると、value は未定義になり、done は true のままになります。

トラバーサルにおけるジェネレーターの応用

js では、配列をトラバースしたい場合、for...of のようなステートメントを使用してトラバースできます。これは、実際には配列にジェネレーター トラバーサーが含まれているためです。自己定義オブジェクトにトラバーサも含まれている場合は、for...of などのトラバーサル ステートメントを通じてカスタム オブジェクトをトラバースできます。このイテレータは、Symbol.iterator プロパティに保存されます。

var myArray = { 0: '你', 1: '的', 2: '名字', length: 3 }; myArray[Symbol.iterator] = function * (){ for(var i = 0; i < this.length; i++) { yield this[i]; } }; for(var item of myArray) { console.log(item); } //你 //的 //名字
ログイン後にコピー

非同期プログラミングにおけるジェネレーターの応用

Javascript の核心は非同期プログラミングであり、各非同期操作は実行結果を返すコールバック関数を提供します。いくつかの操作があり、後の操作が前の操作の結果に依存するとします。

step1(function(value1) { step2(value1, function(value2) { step3(value2, function(value3)) { //some code } }); })
ログイン後にコピー

このようなコードでは、ネストされたコールバックの数が増えると、プログラムが非常に理解しにくくなります。私たちがしなければならないのは、コールバックをフラット化することです。 Promise オブジェクトには、上記の操作を約束します。

step1().then(function(value1){ return step2(value1); }).then(function(value2){ return step3(value2); }).then(function(){ //some code })
ログイン後にコピー

入れ子が少なくなっていることがわかりますが、これは、非同期操作を同期操作に変えることができる場合、つまり、入れ子なしで行うことができる場合には、最も理想的な解決策ではありません。プログラムが理解しやすくなります。ジェネレーター機能はそのような機会を提供します。

function *workflow(){ var value1 = yield step1(); var value2 = yield step2(); var value3 = yield step3(); //some code }
ログイン後にコピー

これが私たちが望む結果であり、非同期プログラミング プログラムは同期プログラミングの形式です。次に行う必要があるのは、このジェネレーターを実行させることなので、エグゼキューターが必要です。 co はエグゼキュータであり、Generator を自動的に実行できます。

co(function *workflow(){ var value1 = yield step1(); var value2 = yield step2(); var value3 = yield step3(); //some code });
ログイン後にコピー

co には制限があります。yield ステートメントの後には Promise オブジェクトまたは Thunk 関数のみを続けることができます。co の詳細については、Ruan 先生の記事「co 関数ライブラリの意味と使用法」を参照してください。ただし、この方法でも外部ライブラリ関数に依存する必要があるため、ES6 では async および await キーワードが提案されました。 async と await は実際には Generator の構文シュガーです。専用のアクチュエーターが付属しているだけです。上記のコードを非同期形式に書き換えます:

async function workflow(){ var value1 = await step1(); var value2 = await step2(); var value3 = await step3(); //some code } var result = workflow();
ログイン後にコピー

async没有了co的限制。await关键字后面可以跟 Promise 对象和原始类型的值(数值、字符串和布尔值,但这时等同于同步操作)。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!