es6 generator 生成器学习总结 使用生成器实现异步请求, async await 的前身

 ============================生成器=========================
       生成器依赖于迭代器,生成器大量使用于react中

       什么是生成器: 生成器是通过构造函数Generator创建的对象(只有js引擎可以使用,不提供外部调用)
        生成器既是一个迭代器,同时又是一个可迭代对象(说明生成器可以使用for of循环)

        如何创建生成器:生成器的创建,必须要使用生成器函数(Generator Function)

        如何创建一个生成器函数: 如下:
          // 在函数名称前面加上一个*号,标记着该函数是一个生成器函数, 和加async标记异步是一样的,但是不能两个同时加
            function *methondsName(){
                // 是给迭代器每一次迭代运行的数据
                // 每一次调用生成器的next()方法,将导致生成器函数运行到下一个yield关键字位置
            }

            或者:
             function* methondsName(){
                 // 是给迭代器每一次迭代运行的数据
                // 每一次调用生成器的next()方法,将导致生成器函数运行到下一个yield关键字位置
            }

            通过生成器函数获取生成器
          const generator = methondsName();

        yeild: 是一个关键字, 该关键字只能在生成器函数内部使用,表达“产生”一个迭代数据

         使用方法:
          function* test() {
            console.log("第一次运行");
            yield 1;
            console.log("第二次运行");
            yield 2;
            console.log("第三次运行")
        }   

        // 迭代运行数组
        function* createIterator(arr) {
            for (const item of arr) {
                yield item;
            }
        }

        // 调用生成一个生成器
        const arr = [1,2,3,4,5,6]
        const ci = createIterator(arr);
        ci.next() // 每一次调用打印数组里面迭代的值,直到迭代完成

       生成器注意:
        1. 生成器可以存在有返回值,在迭代结束的时候return的值会赋值给value(迭代器返回对象的value)的值 
        2. 调用生成器的next() 可以传递参数,传递参数交给yield的表达式的返回值

            例如:
            function* test() {
                let info = yield 1;
                info = yield 2 + info
            }

            const generator = test();
            generator.next() // value: 1, done: false
            generator.next(5) // value: 6, done: false
            generator.next(5) // value: undefined, done: true
        3. 生成器第一次调用next()方法时候,传递的参数没有任何意义
        4. 在生成器内部可以调用其他生成器的函数,调用方式如下:
           
                function* test() {
                    yield 1;
                    yield 2;
                }

                function* test2() {
                    yield* test(); // 这样调用其他生成器的代码
                    yield 3;
                    yield 4;
                }

        5.  生成器的其他API   
           return(): 调用该方法可以提前结束生成器
           throw(): 调用该方法,可以在生成器里面抛出一个错误


           /**
            * 使用生成器来模拟 async await 处理异步 
            * @description:  生成器,来执行异步代码
            * @param : generatorFunc 一个生成器对象
            * @return: 
            */
            function run(generatorFunc) {
                // 执行生成器,创建一个生成器
                const generator = generatorFunc();
                // 先执行生成器的next()方法, 启动生成器
                const result = generator.next();
                // 后面判断是否要继续执行next() 方法
                handleResult(result);

                /**
                * @description: 执行后续生成器的结果
                * @param :  result {*} 生成器对象
                * @return: 
                */
                function handleResult(result) {
                    // 判断后续处理是福继续,如果为true, 则表示迭代失败,为false, 继续迭代
                    if (result.done) {
                        return;
                    }
                    // 然后继续迭代,存在两种数据情况
                    // 1. 迭代的数据是一个promise 异步代码
                    // 2. 迭代的数据是一个其他数据, 也就是同步代码

                    // 此处判断迭代结果 的值是否有一个then函数
                    if (typeof result.value.then === "function") {
                        // 1. 迭代的数据是一个promise 异步代码
                        result.value.then(data => {
                            const nextResult = generator.next(data);
                            handleResult(nextResult);
                        }, err => {
                            // promise 失败, 生成器内部抛出一个错误
                            generator.throw(err);
                            const nextResult = generator.next(data);
                            handleResult(nextResult);

                        })
                    } else {
                        // 2. 迭代的数据是一个其他数据, 也就是同步代码

                        // 把上一次迭代的结果传给下一次迭代
                        const nextResult = generator.next(result.value);
                        handleResult(nextResult);
                    }
                }
            }

            function* task() {
                const d = yield 1;
                console.log(d);
                const dd = yield 1;
                console.log(dd);

                const resp = yield fetch("xxxx.xxx.xxxx");
                console.log(resp)
                const res = yield resp.json();
                console.log(res)
            }
            
            run(task);

你可能感兴趣的:(es6)