Asynchronous programming of es6 generator function

The es6 generator function, we all know that asycn and await are grammatical sugars of the generator function, so how can genertaor implement the functions of asycn and await?

1.thunk Function Replace the function with a single-parameter function that accepts only callback functions as parameters

/* Thunk Functions do not replace expressions, but multiparameter functions, replacing them with a single-parameter function that only accepts callback functions as parameters. */
/* 
    Note fn passes in a function, a method of forming the function, a parameter, and finally a callback
    After two function calls, the function is replaced by a single-parameter function that accepts only callback functions as parameters
 */
var thunk = function(fn) {
    return function() {
        let args = Array.prototype.slice.call(arguments);
        return function (callback) {
            args.push(callback);
            return fn.apply(this,args)
        }
    }
}

2. Examples of generator asynchronous programming

/* Asynchronous execution method */
function timeout(ms,val) {
    return new Promise((res)=>{
        setTimeout(()=>{
            res(val)
        },ms)
    })
}
function *fn(){
    yield timeout(2000,1)
    console.log('222')
    yield timeout(3000,2)
    yield timeout(2000,3)
    return 2;
}

Use while to let the generator function above execute itself

/* res.value Itself is an asynchronous promise method, which is not possible if several promises are associated */
var f = fn();
var res = f.next();
while(!res.done) {
    res.value.then((val)=>{
        console.log(val)
    })
    res = f.next();
}

The printout is not sequential, 13 is output with the same event, 2 is the last output

You can also use promise nesting to make it output sequentially, but that's not good because you may not know how many yield there are, and the nested way doesn't look good

var f = fn();
var res = f.next();
res.value.then((val)=>{
    console.log(val)
    return res = f.next().value
}).then((val)=>{
    console.log(val)
    return res = f.next().value
}).then((val)=>{
    console.log(val)
    return res = f.next().value
})

We define a generator self-executor (note why the thunk function is mentioned, timeout has been encapsulated similarly to thunk)

/* Write an executor for generator */
function *gn(){
    let p1 = yield timeout(2000,1)
    console.log(p1)
    let p2 = yield timeout(3000,2)
    console.log(p2)
    let p3 = yield timeout(2000,3)
    console.log(p3)
    return 2;
}
//  Output 1 2 3 in sequence
/* Pass in gen to execute */
/* The loop actually traverses all yeild s (recursion of functions)
    Root out the Don in the next return value to determine whether to execute to the last,
    Jump out if last*/
function run(fn) {
    var gen = fn();
    function next(data) {
        /* Executing gen.next Initial data is undefined */
        var result = gen.next(data)
        /* If result.done is true, it represents a return to gen and jumps out */
        if(result.done) {
            return;
        }
        /* result.value For promise */
        result.value.then(val=>{
            next(val)
        })
    }
    /* Call last next method */
    next();
}
run(gn)

The above output structures are 123 with an interval of 2s 3s 2s

Although there are grammatical sugars for generator s like async and await, we still need to understand their nature.Believe you understand the essence, let alone master asycn and await

Article Reference Address, Asynchronous Application of Generator Function by Teacher Ruan Yifeng http://es6.ruanyifeng.com/#docs/generator-async

Tags: Javascript Programming

Posted on Thu, 07 Nov 2019 12:42:41 -0800 by nagalenoj