JavaScriptの発電機パート2 -簡単なユースケース
20764 ワード
で説明したジェネレータの動作previous article 複雑ではないが、それは確かに驚くべきであり、非常に最初に把握するのは難しいかもしれない.
したがって、この記事では、より多くの概念を導入する代わりに、私たちは少し休止して、発電機のために涼しい使用ケースを発見している間、我々がこの点について学んだものだけを使います.
次のような機能があるとしましょう.
その場合、それらの値を追加しようとしてはいけません
したがって、これらの数値が実際に定義されているかどうかをチェックする必要があります.
では、再度関数を書き直しましょう.
そしてこれは単なるおもちゃの例です!より複雑なロジックを含む実際のコードベースでは、それらのチェックはさらに複雑になるでしょう.
それで、ここでジェネレータを使用して、より単純な形にコードを戻すことができるならば、どうですか?
以下を見てください.
それがわかるならば
このようにして、実際に定義された値だけを扱うようなコードを書くことができました.
それは本当にそれがそうであるならば、それはあなたのためにチェックするジェネレータ自体です、そして、それはそれに応じて行動します!魔法だね.
しかし、それだけでなく、非常に書くことも可能です!
もちろん、ジェネレータ自体はこの機能を持っていません.これらはイテレータを返し、オプションでいくつかの値をジェネレータに戻すことができます.
それで、我々はラッパーを書かなければなりません
関数を直接呼び出す代わりに:
ジェネレータ自体はあまりしないが、このようなカスタムラッパーを書くことにより、ジェネレータのカスタム動作を付与することができます!そして、それはまさに我々が今することです.
So
でも
例えば、
より具体的には
我々は置き換えることができることを覚えて
我々はほとんどそこにある-任意の時点で我々の発電機が発生した場合
しかし、繰り返し処理が終了しなければ何かを返す必要がある
我々
私たちは
これが起こると
ダミーを作ろう
しかし、追加された数字の1つを変更しましょう
しかし、それを確かめることは我々にとって重要でした
我々は、単にAを加えることによってそれをすることができます
そして、実際には、コードを実行する場合は、単に表示されます
我々のコードはまた、意図通りに動作します
この例の出力は、この特定のコードを実行する際には置かれません.
それは我々が潜在的に産出するどんな発電機も扱うことができる一般的なヘルパーを作成したという事実において、それを産みます
例えば、より複雑な関数を書いたならば
実際、我々のラッパーは、我々の例において、それらの機能が数を返すという事実に頼りません.注意
これは、開発者が発電機についてエキサイティングなものを見つけるものです.それらは非常に規則的に見えるコードにカスタム機能を導入することができます
そして、その機能は文字通り何かをすることができます.発電機は潜在的に無限の可能性を導入し、唯一の制限は我々の想像力です!
そして、次の記事では、特に反応と組み合わせて、それらの可能性を探求し続けるでしょう.だから、これはあなたに興味深い音、それらの将来の記事をお見逃しなく私に従ってください.
読書ありがとう!
したがって、この記事では、より多くの概念を導入する代わりに、私たちは少し休止して、発電機のために涼しい使用ケースを発見している間、我々がこの点について学んだものだけを使います.
次のような機能があるとしましょう.
function maybeAddNumbers() {
const a = maybeGetNumberA();
const b = maybeGetNumberB();
return a + b;
}
関数maybeGetNumberA
and maybeGetNumberB
返り値null
or undefined
. それは、彼らの名前の「多分」が意味するものです.その場合、それらの値を追加しようとしてはいけません
null
), しかし、むしろすぐに保釈して、ちょっと戻りましょう.null
再び.結局のところ、返す方が良いnull
ここでは、いくつかの予測不可能な値よりもnull/undefined
数または別でnull/undefined
.したがって、これらの数値が実際に定義されているかどうかをチェックする必要があります.
function maybeAddNumbers() {
const a = maybeGetNumberA();
const b = maybeGetNumberB();
if (a === null || a === undefined || b === null || b === undefined) {
return null;
}
return a + b;
}
これは大丈夫ですがa
はどちらかnull
またはundefined
, 本当に電話をかける点はないmaybeGetNumberB
すべての関数.それは、我々がすでにAを返すということを知っているからですnull
とにかく.では、再度関数を書き直しましょう.
function maybeAddNumbers() {
const a = maybeGetNumberA();
if (a === null || a === undefined) {
return null;
}
const b = maybeGetNumberB();
if (b === null || b === undefined) {
return null;
}
return a + b;
}
ユウ読みやすい3ライナーから、これはすぐにコードの10行(空の行をカウントしない)に成長した.この関数はif
ケース、あなたはそれが何を理解するために通過する必要があります.そしてこれは単なるおもちゃの例です!より複雑なロジックを含む実際のコードベースでは、それらのチェックはさらに複雑になるでしょう.
それで、ここでジェネレータを使用して、より単純な形にコードを戻すことができるならば、どうですか?
以下を見てください.
function* maybeAddNumbers() {
const a = yield maybeGetNumberA();
const b = yield maybeGetNumberB();
return a + b;
}
私たちがそれを与えることができるならばyield <something>
式のチェック機能<something>
は実際の値ではなくnull
or undefined
?それがわかるならば
<something>
is null
or undefined
, 我々は、ちょうど早く保釈して、帰りますnull
, 正確に我々のコードのより詳細なバージョンのように.このようにして、実際に定義された値だけを扱うようなコードを書くことができました.
それは本当にそれがそうであるならば、それはあなたのためにチェックするジェネレータ自体です、そして、それはそれに応じて行動します!魔法だね.
しかし、それだけでなく、非常に書くことも可能です!
もちろん、ジェネレータ自体はこの機能を持っていません.これらはイテレータを返し、オプションでいくつかの値をジェネレータに戻すことができます.
それで、我々はラッパーを書かなければなりません
runMaybe
- これはジェネレータにこの機能を与えます.関数を直接呼び出す代わりに:
const result = maybeAddNumbers();
このラッパに対する引数として呼び出します.const result = runMaybe(maybeAddNumbers());
これは非常に頻繁にジェネレータで表示されるパターンです.ジェネレータ自体はあまりしないが、このようなカスタムラッパーを書くことにより、ジェネレータのカスタム動作を付与することができます!そして、それはまさに我々が今することです.
So
runMaybe
明らかに関数であり、1つの引数を受け付けます-ジェネレータによって生成されたイテレータfunction runMaybe(iterator) {
}
このイテレータを実行しますwhile
ループ.そのためには、イテレータを初めて呼び出す必要がありますdone
プロパティーfunction runMaybe(iterator) {
let result = iterator.next();
while(!result.done) {
}
}
ループ内で2つのオプションがあります.If result.value
is null
or undefined
繰り返し処理を中断して戻ります.null
. そうしましょうfunction runMaybe(iterator) {
let result = iterator.next();
while(!result.done) {
if (result.value === null || result.value === undefined) {
return null;
}
}
}
あなたはすぐに我々はすぐに反復を停止していることがわかりますreturn
そして、我々はnull
我々のラッパーから.でも
result.value
実際の、定義された値です、我々は発電機に「それを返します」.例えば、
yield maybeGetNumberA()
, それがわかるならばmaybeGetNumberA()
実際には、私たちはyield maybeGetNumberA()
を返します.より具体的には
maybeGetNumberA()
番号5に評価し、変更したいconst a = yield maybeGetNumberA();
into const a = 5;
. ご覧のように、私たちはどんな値でも値を変更したくないが、単に発電機に戻します.我々は置き換えることができることを覚えて
yield <something>
を返します.next
メソッド.そうしましょう!function runMaybe(iterator) {
let result = iterator.next();
while(!result.done) {
if (result.value === null || result.value === undefined) {
return null;
}
// we are passing result.value back
// to the generator
result = iterator.next(result.value)
}
}
そして、あなたが見ることができるように、新しい結果は現在result
再び変数.特に宣言しましたresult
with let
それで、それは可能です.我々はほとんどそこにある-任意の時点で我々の発電機が発生した場合
null/undefined
値をyieldするとき、私たちはnull
我々からrunMaybe
ラッパー.しかし、繰り返し処理が終了しなければ何かを返す必要がある
null/undefined
値.結局、我々が我々の発電機で2つの実数を受け取るならば、我々はラッパーから彼らの合計を返したいです!我々
maybeAddNumbers
発電機はreturn
文.私たちは
return <something>
ジェネレータで、イテレータがオブジェクトを返す原因となります{ value: <something>, done: true }
からnext
コール.これが起こると
while
ループは実行を停止しますdone
プロパティはtrue
. しかし、その最後の値はa + b
値はまだresult.value
プロパティ!それで最後には単純に返すことができます.function runMaybe(iterator) {
let result = iterator.next();
while(!result.done) {
if (result.value === null || result.value === undefined) {
return null;
}
result = iterator.next(result.value)
}
// just return the last value
// after the iterator is done
return result.value;
}
そしてそれだ!ダミーを作ろう
maybeGetNumberA
and maybeGetNumberB
関数.最初に実数を返しましょうconst maybeGetNumberA = () => 5;
const maybeGetNumberB = () => 10;
コードを実行し、結果をログ出力する場合function* maybeAddNumbers() {
const a = yield maybeGetNumberA();
const b = yield maybeGetNumberB();
return a + b;
}
const result = runMaybe(maybeAddNumbers());
console.log(result);
期待されるように、コンソールの15番です.しかし、追加された数字の1つを変更しましょう
null
:const maybeGetNumberA = () => null;
const maybeGetNumberB = () => 10;
コードログの実行null
!しかし、それを確かめることは我々にとって重要でした
maybeGetNumberB
関数は最初の関数のときに呼び出されません.maybeGetNumberA
- リターンnull/undefined
. それで、我々が本当に成功するならば、チェックしてください.我々は、単にAを加えることによってそれをすることができます
console.log
2番目の関数const maybeGetNumberA = () => null;
const maybeGetNumberB = () => {
console.log('B');
return 10;
}
我々が書くならばrunMaybe
正しく、ヘルパー、手紙B
この例を実行するとコンソールに表示されません.そして、実際には、コードを実行する場合は、単に表示されます
null
コンソールでは、何も他の.これは、私たちのヘルパーが実際に発生した後にジェネレータを実行停止しますnull/undefined
値.我々のコードはまた、意図通りに動作します
null
- いずれの組み合わせにおいてもconst maybeGetNumberA = () => undefined;
const maybeGetNumberB = () => 10;
const maybeGetNumberA = () => 5;
const maybeGetNumberB = () => null;
const maybeGetNumberA = () => undefined;
const maybeGetNumberB = () => null;
などこの例の出力は、この特定のコードを実行する際には置かれません.
それは我々が潜在的に産出するどんな発電機も扱うことができる一般的なヘルパーを作成したという事実において、それを産みます
null/undefined
値.例えば、より複雑な関数を書いたならば
function* maybeAddFiveNumbers() {
const a = yield maybeGetNumberA();
const b = yield maybeGetNumberB();
const c = yield maybeGetNumberC();
const d = yield maybeGetNumberD();
const e = yield maybeGetNumberE();
return a + b + c + d + e;
}
我々はそれを実行することができますrunMaybe
ラッパーも任意の問題なし!実際、我々のラッパーは、我々の例において、それらの機能が数を返すという事実に頼りません.注意
runMaybe
我々は、すべての数型については言及しません.だから、あなたのジェネレータで使用されている値の種類は-番号、文字列、オブジェクト、配列、より複雑なデータ構造-それはまだ我々のヘルパーで動作します!これは、開発者が発電機についてエキサイティングなものを見つけるものです.それらは非常に規則的に見えるコードにカスタム機能を導入することができます
yield
もちろんコールする).特定の方法でジェネレータを繰り返すラッパーを作成する必要があります.このように、ラッパーは基本的に“ジェネレータ”カスタム機能を補助する!そして、その機能は文字通り何かをすることができます.発電機は潜在的に無限の可能性を導入し、唯一の制限は我々の想像力です!
そして、次の記事では、特に反応と組み合わせて、それらの可能性を探求し続けるでしょう.だから、これはあなたに興味深い音、それらの将来の記事をお見逃しなく私に従ってください.
読書ありがとう!
Reference
この問題について(JavaScriptの発電機パート2 -簡単なユースケース), 我々は、より多くの情報をここで見つけました https://dev.to/mpodlasin/generators-in-javascript-part-ii-simple-use-case-g6fテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol