美文网首页
ES6的Generator对象完成文件读取并消费的异步应用过程

ES6的Generator对象完成文件读取并消费的异步应用过程

作者: JohnYuCN | 来源:发表于2022-02-04 16:53 被阅读0次

    ES6 Generator概念的引入,虽然从本质上讲是一个“语法糖”的概念,但它完全放飞了“异步函数设计”和“协程设计”两个领域,本文从一个实例的角度分析了它的使用过程。


    海南儋州市海花岛灯光秀--2022-1

    1. 使用《回调函数》设计的generator函数

    /**
     * 异步函数gen(也可理解为协程)中调用《回调函数版本的异步函数》
     * 优点是调用方式同步化(在main中)
     * 缺点是使用闭包获取generator对象,来完成回调中的next()
     */
    
    let fs=require('fs')//引入回调函数版的fs模块
    
    function* gen(filename){
        /*
            gen函数的第一段(发起异步调用)
        */
        console.log("马上就要进行文件读取。。。")
        let fileContent=yield fs.readFile(filename,'utf-8',(err,data)=>{
            if(!err){
                //需要以闭包的方式获取generator对象
                closureGen.next(data)//data将成为yield fs.readFile的返回值
            }
        })
        /*
            gen函数的第二段(回调处理)
        */
        console.log(fileContent)
        console.log("文件内容读取完毕。。。")
    }
    
    function main(){
        let closureGen=gen('./test1.rest')
        //如没有此行,则gen函数从定义的位置去查询closureGen,则无法查到闭包环境中的closureGen
        //当然也可以将gen函数定义为main函数的内部函数,从而closureGen成为闭包环境变量
        global.closureGen=closureGen
        closureGen.next()
    }
    main()
    

    2. 使用《Promise》设计的generator函数(鼓励使用!)

    /**
     * 异步函数gen(也可理解为协程)中调用《Promises版本的异步函数》
     * 优点是gen函数中的实现非常自然(只有加入yield关键字的成本),同时不必关心闭包变量(generator对象)的问题
     * 缺点是在调用时,需要使用promise语法,同时也需要熟悉generator对象的next方法的传参技巧
     */
    const fs=require('fs/promises')//promise版本的fs模块
    
    function* gen(filename){
        /*
            gen函数的第一段(发起异步调用)
        */
        console.log("马上就要进行文件读取。。。")
        let fileContent=yield fs.readFile(filename,'utf-8')
        /*
            gen函数的第二段(回调处理)
        */
        console.log(fileContent)
        console.log("文件读取完毕。。。")
    }
    
    function main(){
        let g=gen("./test1.rest")
        g.next().value
        .then(data=>{
            g.next(data)
        })
    }
    main()
    
    

    3. 使用《co》进行调用时封装的《Promise》版本

    
    /**
     * 此版本gen的实现与Promise版本完全一致,但引入co库,解决调用代码的复杂度
     */
    const co=require('co')//引入TJ的cooperate库
    const fs=require('fs/promises') //promise版本的fs模块
    
    function* gen(filename){
        //内容与promise版本完全一至
    }
    
    function main(){
        co(gen,"./test1.rest")
    }
    main()
    

    相关文章

      网友评论

          本文标题:ES6的Generator对象完成文件读取并消费的异步应用过程

          本文链接:https://www.haomeiwen.com/subject/nseskrtx.html