zoukankan      html  css  js  c++  java
  • es6 generator函数的异步编程

    es6 generator函数,我们都知道asycn和await是generator函数的语法糖,那么genertaor怎么样才能实现asycn和await的功能呢?

      1.thunk函数    将函数替换成一个只接受回调函数作为参数的单参数函数

    /* Thunk 函数替换的不是表达式,而是多参数函数,将其替换成一个只接受回调函数作为参数的单参数函数。 */
    /* 
        注 fn 传入的是一个函数,传入一个函数形成的方法,传入参数,最后传入callback
        在经过两次函数调用后,该函数就换成一个只接受回调函数作为参数的单参数函数
     */
    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.generator异步编程的示例

    /* 异步执行方法 */
    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;
    }

      使用while去让上面的generator函数自执行

    /* res.value本身是个异步的promise方法,如果几个promise 有关联那么这样就不行了 */
    var f = fn();
    var res = f.next();
    while(!res.done) {
        res.value.then((val)=>{
            console.log(val)
        })
        res = f.next();
    }

      在浏览器可知打印的结果,并不是顺序的,1 3 是同以事件输出的,2是最后输出的

      我们也可以使用promise嵌套使其按顺序输出,但是这种并不好,因为可能不知道具体有几个yield,嵌套的方式写的不好看

    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
    })

      我们定义一个generator自执行器(注为什么要提thunk函数,timeout已经经过thunk类似的封装了)

    /* 写一个适合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;
    }
    //  按顺序输出 1 2 3
    /* 传入要执行的gen */
    /* 其实循环遍历所有的yeild (函数的递归)
        根绝next返回值中的done判断是否执行到最后一个,
        如果是最后一个则跳出去*/
    function run(fn) {
        var gen = fn();
        function next(data) {
            /* 执行gen.next 初始data为undefined */
            var result = gen.next(data)
            /* 如果result.done 为true 则代表执行到了gen的return,直接跳出去 */
            if(result.done) {
                return;
            }
            /* result.value 为promise */
            result.value.then(val=>{
                next(val)
            })
        }
        /* 调用上一个next方法 */
        next();
    }
    run(gn)

    上述输出结构,分别是 1 2 3 ,间隔时间 2s 3s 2s

      虽然已经有async和await这样的generator的语法糖了,但是我们还是需了解以下他们的本质。相信您了解了本质,掌握asycn和await更不在话下

      文章参考地址,阮一峰老师的  Generator 函数的异步应用 http://es6.ruanyifeng.com/#docs/generator-async

  • 相关阅读:
    086 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 03 面向对象基础总结 01 面向对象基础(类和对象)总结
    085 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 02 构造方法介绍 04 构造方法调用
    jQuery UI组件库Kendo UI使用技巧小分享
    Kendo UI ListView模板功能,让Web开发更轻松
    UI组件套包DevExpress ASP.NET Core v20.2新版亮点:全新的查询生成器
    Devexpress WinForms最新版开发.NET环境配置Visual Studo和SQL Server对应版本
    全新的桌面应用数据可视化呈现方式,Sankey Diagram控件你了解多少?
    java中的递归方法
    连接数据库查询 将查询结果写入exce文件中
    java连接mysql数据查询数据
  • 原文地址:https://www.cnblogs.com/czkolve/p/10902303.html
Copyright © 2011-2022 走看看