最新公告
  • 欢迎您光临网站无忧模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 异步无处不在:Generator 异步方案(五)

    正文概述 掘金(勾崽)   2021-01-15   507

    关于异步的知识点,终于要结束了!

    本篇就来重点说说如何将 Generator 写进异步中

    Generator 异步方案

    将调用 ajax 的代码写到生成器函数的 yield 后面,每次的异步执行,都要在 yield 中暂停,调用的返回结果是一个 Promise 对象。

    我们可以从迭代器对象的 value 属性获取到 Promise 对象,然后使用 .then 进行链式调用处理异步结果。

    结果处理的代码叫做执行器,就是具体负责运行逻辑的代码。

    function ajax(url) {
        ……
    }
    
    ​// 声明一个生成器函数
    function * fun(){
        yield myAjax('./d1.json')
        yield myAjax('./d2.json')
        yield myAjax('./d3.json')
    }​
    
    // 返回 遍历器对象 
    var f = fun();
    // 生成器函数的执行器 
    // 调用 next 方法,执行异步代码
    var g = f.next();
    g.value.then(data=>{
        console.log(data);
        // console.log(f.next());
        g = f.next();
        g.value.then(data=>{
            console.log(data)
            // g.......
        })
    })
    

    而执行器的逻辑中,是相同嵌套的,因此可以写成递归的方式对执行器进行改造:

    // 声明一个生成器函数
    function * fun(){
        yield myAjax('./d1.json')
        yield myAjax('./d2.json')
        yield myAjax('./d3.json')
    }​
    
    // 返回 遍历器对象 
    var f = fun();
    // 递归方式 封装
    // 生成器函数的执行器
    function handle(res){
        if(res.done) return;
        res.value.then(data=>{
            console.log(data)
            handle(f.next())
        })
    }
    handle(f.next());
    

    然后,再将执行的逻辑,进行封装复用,形成独立的函数模块。

    function co(fun) {
        // 返回 遍历器对象
         var f = fun();
        // 递归方式 封装
        // 生成器函数的执行器
        function handle(res) {
            if (res.done) return;
            res.value.then(data => {
                console.log(data)
                handle(f.next())
            })
        }
        handle(f.next());
    }​
    
    co(fun);
    

    封装完成后,我们再使用时只需要关注 Generator 中的 yield 部分就行了。

    function co(fun) {
        ……
    }
    
    ​function * fun(){
        yield myAjax('./d1.json')
        yield myAjax('./d2.json')
        yield myAjax('./d3.json')
    }
    

    此时你会发现,使用 Generator 封装后,异步的调用就变得非常简单了。

    但是,这个封装还是有点麻烦,有大神帮我们做了这个封装,相当强大:github.com/tj/co ,感兴趣可以研究一下。

    而随着 JS 语言的发展,更多的人希望类似 co 模块的封装能够写进语言标准中,而我们直接使用这个语法规则就行了。

    其实你也可以对比一下,使用 co 模块后的 Generator 和 async 这两段代码:

    //  async / await
     async function callAjax(){
         var a = await myAjax('./d1.json')
         console.log(a);
         var b = await myAjax('./d2.json');
         console.log(b)
         var c = await myAjax('./d3.json');
         console.log(c)
     }
      
    // 使用 co 模块后的 Generator
     function * fun(){
        yield myAjax('./d1.json')
        yield myAjax('./d2.json')
        yield myAjax('./d3.json')
    }
    

    你应该也发现了,async 函数就是 Generator 语法糖,不需要自己再去实现 co 执行器函数或者安装 co 模块。

    写法上将 * 星号去掉换成放在函数前面的 async,把函数体的 yield 去掉,换成 await。

    简直完美!

    async function callAjax(){
         var a = await myAjax('./d1.json')
         console.log(a);
         var b = await myAjax('./d2.json');
         console.log(b)
         var c = await myAjax('./d3.json');
         console.log(c)
     }
    callAjax();
    

    我们再来看一下 Generator。

    相信下面的代码,你能很轻松地阅读。

    function * f1(){
        console.log(11)
        yield 2;
        console.log('333')
        yield 4;
        console.log('555')
    }​
    
    var g = f1();
    g.next();
    console.log(666);
    g.next();
    console.log(777);
    

    代码运行结果:

    异步无处不在:Generator 异步方案(五)

    带着 Generator 的思路,我们再回头看看那个 async 的面试题。

    请写出以下代码的运行结果:

    setTimeout(function () {
        console.log('setTimeout')
    }, 0)​
    
    async function async1() {
        console.log('async1 start')
        await async2();
        console.log('async1 end')
    }​
    
    async function async2() {
        console.log('async2')
    }
    
    ​console.log('script start')​
    
    async1();​
    
    console.log('script end')
    

    运行结果:

    异步无处不在:Generator 异步方案(五)

    是不是恍然大明白呢(●'◡'●)。


    下载网 » 异步无处不在:Generator 异步方案(五)

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元