created at 2019-04-08

conclusion

  • Asynchronous programming solutions
  • It can be thought of as a state machine that encapsulates multiple internal states
  • Returns a pointer object to the internal state (the traverser object Interator), so it can be understood as an traverser object generator
  • Yield, which defines different internal states, yield followed by expressions.
  • Yield expressions can only be placed in Generator functions
  • (yield expression) returns no value at all, and the argument to next() can be considered the return value of the previous yield.
  • The V8 engine simply ignores the first next() argument because there is no last yield
  • When the next method is called, the pointer executes from the head of the function or where it last stopped until the next yield expression or return is encountered
  • When the value attribute of next’s return value is the result of the yield expression or the value of the return, and when the done attribute is true, the yield ends
  • Const obj = {* myGeneratorMethod(){}} obj = {myGeneratorMethod: function* (){}}
  • Yield * is used to execute another generator function in one generator function, and the yield in the current generator will continue only after all the other’s yield has been executed

Basic grammar

 function* generatorTest() {
    console.log('Statement before first yield');
    yield 'yield 1'
    yield 'Yield 3: Parentheses in expressions' + (yield 'yield 2: in expression')
    console.log('Yield after return before return');
    return 'return'
}

const gt = generatorTest()
console.log(gt);
// Traversal object

/* * The first call is executed from the head of the function. If there is no yield, the next will execute the statements */
console.log(gt.next());
// The first yield statement
// {value: "yield 1", done: false}

console.log(gt.next());
// {value: "yield 2: in expression", done: false}

console.log(gt.next());
// {value: "yield 3: undefined", done: false}
// Undefined because next has no arguments

console.log(gt.next());
// yield before return
// {value: "return", done: true}

console.log(gt.next());
// {value: "undefined", done: true}

Copy the code

Implement the Fibonacci sequence

link

Add Iterator to native objects

Show the effect of for of on generator first

function* generatorForOf(){
    yield 1;
    yield 2;
    return 3;
}
/* * for of can iterate over Iterator generated by Generator * gt cannot be iterated again because it has completed execution * does not iterate over return values */
for (let item of generatorForOf()) {
    console.log('for of :', item);
}
Copy the code

Add an iterator to a native object so it can be iterated for of

function* objectAddIterator(obj) {
    const props = Reflect.ownKeys(obj)

    for (const key of props) {
        yield [key, obj[key]]
    }
}

const nativeObj = {
    a: 12.b: 34[Symbol('symbol c')]: 3
}

for (const [key, value] of objectAddIterator(nativeObj)) {
    console.log(typeof key === 'symbol' ? key.description : key, value);
}
Copy the code

Application scenarios

Asynchronous Ajax requests

The loading function in the code has too many lines of code and is not a key code, so it is not shown. Viewing the Loading code

<div id="ajax">The initial data</div>
<button onclick="getSomeList()">Requesting Ajax data</button>
Copy the code
function requestData(callback) {
    function ajaxFn() {
        setTimeout((a)= > {
            ar.next('Ajax returns results')},2000);
    }

    function* asyncReqData() {
        loading(true)
        const result = yield ajaxFn()
        callback(result)
        loading(false)}const ar = asyncReqData()
    ar.next()
}

function getSomeList() {
    requestData((res) = > {
        document.getElementById('ajax').innerHTML = res
    })
}
Copy the code

Control the flow of synchronous operations

function controlFlow() {
    const child1 = [(a)= > {console.log(The '-'.1); return 'return 1'= > {}, ()console.log(The '-'.2); return 'return 2'}]
    const child2 = [(a)= > {console.log(The '-'.3); return 'return 3'= > {}, ()console.log(The '-'.4); return 'return 4'}]
    function* generatorControl(child) {
        console.log('= = = = = = = = = = =');
        for (let i = 0; i < child.length; i++) {
            yield child[i]()
        }
    }
    let parent = [{c: child1}, {c: child2}];

    function* parentFn(p){
        for (let i=0; i< p.length; i++){
            yield* generatorControl(p[i].c); }}for (let step of parentFn(parent)) {
        console.log(step);
    }
}

controlFlow()
Copy the code

This article includes learning and practicing the basics of generate, and some insights! [Will continue to learn and update]

For details, please refer to the link below

Reference:

  • Refer to the article

Welcome to Github