Generator learning record

generator

Basics

  1. The generator has the ability to pause and resume code execution within a function block.
  2. Create generator:
    //The asterisk identifying the generator function is not affected by the spaces on both sides
     function* generator(){
         ...
     }
    
  3. Note: arrow functions cannot be used to define generator functions
  4. Calling the generator function will generate a generator object. The generator object is suspended at the beginning. Similar to the iterator, the generator object also implements the iterator interface and has the next() method. Calling the next() method can make the generator start or resume execution

yield

  1. The yield keyword allows the generator to stop and start execution. The generator will execute normally before encountering the yield keyword. After encountering this keyword, it will stop, and the state of the function scope will be retained. The stopped generator function can only resume execution by calling the next() method
  2. The yield keyword can only be used inside the generator. If it is used elsewhere, an error will be thrown
    // invalid
     function* generator(){
         function a(){
             yield;
         }
     }
    

Realize input and output

  1. The yield keyword that last suspended the generator function receives the first value passed to the next() method
     function* generator(initial) {
         console.log(initial);
         console.log(yield);
         console.log(yield);
     }
     let generatorObj = generator('foo');
     generatorObj.next('bar'); //foo the first value passed in will not be called because the first time next() is to execute the generator function
     generatorObj.next('test'); //test
     generatorObj.next('new'); //new
    
  2. For both input and output
     function* generator() {
         return yield 'test';
     }
     let generatorObj = generator();
     console.log(generatorObj.next()); //value: 'test', done: 'false'
     console.log(generatorObj.next('new')); //value: 'new', done: 'true'
    

Generate iteratable objects

Using asterisks to enhance yield's behavior allows him to iterate over one iteratible object, producing one value at a time

function* generator() {
    yield*[1, 2, 3];
}
for (const x of generator()) {
    console.log(x);
}

Early termination generator

Both the return() and throw() methods can be used to force the generator to close

  1. return(): it cannot be recovered after it enters the closed state. Subsequent calls to next() will display the state of done:true, and any return value provided will not be stored or propagated

     function* generator() {
         for (const x of [1, 2, 3]) {
             yield x;
         }
     }
     const g = generator();
     console.log(g.next()); // { value: 1, done: false }
     console.log(g.return(10)); // { value: 10, done: true }
     console.log(g.next()); // { value: undefined, done: true }
     console.log(g.next()); // { value: undefined, done: true }
    
  2. throw(): a provided error will be injected into the generator object during pause. If the error is not handled, the generator will close; If this error is handled inside the generator function, the generator will not close and can resume execution. The error handling will skip the corresponding yield

     function* generator() {
         for (const x of [1, 2, 3]) {
             yield x;
         }
     }
     const g = generator();
     console.log(g); // generator {<suspended>}
     try {
         g.throw('error');
     } catch (e) {
         console.log(e); // error
     }
     console.log(g); // generator {<closed>}
    
     function* generator() {
         for (const x of [1, 2, 3]) {
             try{
                 yield x;
             }catch(e){}
         }
     }
     const g = generator();
     console.log(g.next()); // { value: 1, done: false }
     g.throw('error');
     console.log(g.next()); // { value: 3, done: false }
    

Tags: Javascript Front-end

Posted by Coreyjames25 on Sat, 21 May 2022 05:20:49 +0300