• Generator异步方案


    Generator 函数

    Generator 函数 是一种懒函数,相比普通函数而言,前面多个 *,但是使用起来大不同。

    const foo = function * () {
    	yield "foo";
    };
    
    const generator = foo();
    let result = generator.next();
    console.log(result);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    首先先创建generator 实例,然后调用next 方法,让函数进行运行。会返回当前yield后的值 和 generator实例状态。

    当我们通过next 传值时,会将值赋给 上个yield 的结果并且返回下一个yield后的值。

    const foo = function * () {
        let result = yield "foo";
        console.log(result, "yield");
      
    };
    
    const generator = foo();
    let result = generator.next();
    generator.next("bar");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    通过generator.throw() 方法主动抛出异常

    const foo = function * () {
        try {
            let result = yield "foo";
            console.log(result, "yield");
        } catch (error) {
            console.log(error);
        }
        
      
    };
    
    const generator = foo();
    let result = generator.next();
    generator.throw(new Error("ddd"));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    使用Generator 函数构造异步函数

    function ajax(url) {
        return new Promise(function(resolve, reject){
            var xhr = new XMLHttpRequest();
            xhr.open('GET',url);
            xhr.responseType = 'json';
            xhr.onload = function() {
                if(this.status == 200) {
                    resolve(this.response);
                } else {
                    reject(this.statusText);
                }
            }
            xhr.send();
    
        })
    }
    
    const foo = function * () {
        let result1  = yield ajax("/api/book.json");
        console.log(result1);
    
        let result2  = yield ajax("/api/user.json");
        console.log(result2);
    };
    
    const generator = foo();
    generator.next().value.then(result =>{
        return generator.next(result).value
    }).then(result =>{
        return generator.next(result).value
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    生成器方法封装

    上边方法有个局现性,要手写各种情况,不智能啊,可以用递归解决

    const foo = function * () {
        try {
            let result1  = yield ajax("/api/book.json");
            console.log(result1);
    
            let result2  = yield ajax("/api/user.json");
            console.log(result2);
        } catch (error) {
            console.log(error);
        }
      
    };
    
    
    function co(generatorFun) {
      const g = generatorFun();
      function handleResult(result){
        // 生成器函数结束
        if(result.done) return;
        result.value.then(data =>{
           handleResult(g.next(data));
        }, err => {
            g.throw(new Error(err));
        })
      }
      handleResult(g.next());
    }
    co(foo);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    Generator vs async/await

    async/await 本质上是Generator的语法糖,内部帮我们封装了生成器函数,比如上面的例子改写

    const foo = async function() {
        try {
            let result1  = await ajax("/api/book.json");
            console.log(result1);
    
            let result2  = await ajax("/api/user.json");
            console.log(result2);
        } catch (error) {
            console.log(error);
        }
      
    };
    
    foo().then(result=> {
        console.log("全部执行完成");
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
  • 相关阅读:
    图解python | 面向对象编程
    (面试题)面试官为啥总是让我们手撕call、apply、bind?
    Java实现JSON{参数}占位符名称替换指定的多个变量值
    MySQL(二)事务
    内网渗透知识 ——(一)、工作组、域、域控、活动目录
    MySQL案例详解 三:MMM高可用架构及其故障切换
    【设计模式专题】观察者模式实战详细分析
    Python 教程之控制流(1)python中的循环
    亚马逊云科技加速大语言模型的创新应用
    YOLOv5使用pycocotools进行评估
  • 原文地址:https://blog.csdn.net/sanfeng_hu/article/details/128047811