JavaScript ES 6+ミッドレンジ(4)ジェネレータ


この文章は鄭在南開発者のインフラ講座JavaScript ES 6+中級編を知るをまとめた.
1.概念generatorは、関数表示前に*を付けたやつです.こいつはnext()メソッドを呼び出すと、yieldキーワードに出会う前に実行する.宣言と簡単な運用は以下の通りです.next()メソッドが呼び出され、オブジェクトがvalueおよびdoneのパーセントであることがわかります.
function* gen() {
 console.log(1);
 yield 1;
 console.log(2);
 yield 2;
 console.log(3);
 yield 3;
}
const gen = gene();
gen.next();	
// 1
// {value: 1, done: false}

gen.next();	
// 2
// {value: 2, done: false}

gen.next();	
// 3
// {value: 3, done: false}

gen.next();	
// {value: undefined, done: true}
オブジェクト内でサムネイル関数が宣言された場合、*は変数名の前に配置されます.教室でも同じです.
const obj = {
  gen1: function* () {.
  *gen2 () { yield }
}

class A {
  *gen () { yield }
}
                      
2.反復器としてのジェネレータ
const obj = {
  a: 1,
  b: 2,
  c: 3,
  *[Symbol.iterator] () {
    for(let prop in this) {
      yield [prop, this[prop]];
    }
  }
}

console.log(...obj);
// ["a", 1], ["b", 2], ["c", 3]

for(let p of obj) {
  console.log(p);
}
// ["a", 1]
// ["b", 2]
// ["c", 3]
iteratorをオブジェクトに適用するには、Symbol.iteratorがオブジェクトに戻る必要があります.オブジェクトはnext()メソッドを返さなければなりません...done property戻りなどのルールを適用する必要があるが,generatorを用いてyieldを適切に使用すると,複雑な実現の必要性が減少する.yieldのキーワードの後ろに*の要素があり、後ろにiteratorの要素があれば、iteratorの内部要素を返します.
function* gen() {
  yield* [1, 2, 3];
  yield* 'abc';
}

const gene = gen();
gene.next();
// {value: 1, done: false}

gene.next();
// {value: 2, done: false}

gene.next();
// {value: 3, done: false}

gene.next();
// {value: 'a', done: false}
// ...
yieldの後にgeneratorを使用することもできます.そうなると複雑になります.大きい...🤣
3.収益と価値の分配
まず例を見てみましょう.
function gen() {
  let first = yield 1;
  console.log(first);
  
  let second = yield first + 2;
  console.log(second);
}

const gene = gen();
gene.next();
// {value: 1, done: false)

gene.next();
// {value: NaN, done: false}
上記の例では、첫번째 yieldと遭遇すると、value 1が返され、first 변수に割り当てられるようになる.しかし、事実はそうではない.完成品はvalueオブジェクトとdoneオブジェクトを返しますが、변수에 값을 할당하지 않는다です.したがって、두 번째 yieldが行われると、NaNが返される.firstに適切な値を指定する場合は、2番目のnextメソッドを呼び出すとき(gene.next(10))、パラメータに値を入力するだけです.
4.非同期処理例
次の例は、1000번째の後にユーザを導入し、4번째(1004)6번째(1006)のユーザの情報を得ることである.コードをゆっくり味わって、理解してみましょう.😳. 特にgeneratorを人字に変えて、fetchWrapperからthenに変えてからnextと呼んで、理解してください!
const fetchWrapper = (gen, url) => fetch(url)
	.then(res => res.json())
	.then(res => gen.next(res));

function getNthUserInfo() {
  const [gen, from, nth] = yield;
  const req1 = yield fetchWrapper(gen, `https://api.github.com/users?since=${from || 0}`);
  const userId = req1[nth - 1 || 0].id;
  console.log(userId);
  
  const req2 = yield fetchWrapper(gen, `https://api.github.com/user/${userId}`);
  console.log(req2);
}

const runGenerator = (generator, ...rest) => {
  const gen = generator();
  gen.next();
  gen.next([gen, ...rest]);
}

runGenerator(genNthUserInfo, 1000, 4);
runGenerator(genNthUserInfo, 1000, 6);