js迭代器与生成器及实现async await

259 阅读2分钟

迭代器Iterator

迭代模式:是一种设计模式,用于统一迭代过程。

javascript规定如果一个对象有next方法并且该方法返回一个对象,该对象格式如下

{ value:值,done:是否迭代完成(true or false) }

        const arr = [1, 2, 3, 4, 5];
        //创建迭代器 迭代数组
        const iterator = {
            i: 0, //当前数组下标
            next() {
                var result = {
                    value: arr[this.i],
                    done: this.i >= arr.length   //为true时迭代完成
                }
                this.i++;
                return result
            }
        }

image.png

可迭代对象

可迭代对象都有一个标志属性Symbol.iteratorfor of循环用于遍历可迭代对象

     //手动创建可迭代对象
        var obj = {
            [Symbol.iterator]() {
                return {
                    next() {
                        return {
                            value: 1,
                            done: false
                        }
                    }
                }
            }
        }
        const arr = [1, 2, 3, 4];   //数组是一个可迭代对象
        const iterator = arr[Symbol.iterator]();
        let result = iterator.next();
        while (!result.done) {
            const item = result.value;
            console.log(item);        // 1 2 3 4
            result = iterator.next()
        }
        //等同于上面效果的代码如下,for of相当于是语法糖
         for (const item of arr) {
            console.log(item)    // 1 2 3 4
        }

生成器Generator

生成器既是一个迭代器,又是一个可迭代对象

    //书写一个生成器函数 function后面加个*
        function* method() {
            //生成器内部是为了给生成器提供迭代数据
            //每次调用生成器的next方法,将导致生成器函数运行到下一个yield关键字位置
            //yield关键字只能在生成器函数内部使用,表示产生一个迭代数据
            console.log('第一次运行')
            let info = yield 1;
            console.log(info + 'next传过来的参数')
            console.log('第二次')
            yield 2;
            console.log('第三次')
            return '第一次迭代结束done为true时的value返回值'
        }
        const generator = method(); //注意这一步并不会执行method,只是得到一个迭代器

image.png

基于Generator实现async await

 //利用生成器实现async await效果
       function* task() {
            const d = yield 1;
            console.log(d)    // 1
            const resp = yield fetch("http://localhost:8080/test", {
                method: 'GET'
            });   
            // console.log(resp)  异步请求服务器端返回的结果
        }
        run(task)

        function run(generatorFunc) {
            const generator = generatorFunc();
            let result = generator.next(); //启动任务(开始迭代),得到迭代数据
            handleResult()
                //对result进行处理
            function handleResult() {
                if (result.done) {
                    return //迭代完成
                }
                //若没有完成 迭代的数据可能是一个Promise 或是其他数据
                if (typeof result.value.then == 'function') {
                    //异步
                    result.value.then(data => {
                        result = generator.next(data)
                        handleResult()
                    }, err => {
                        result = generator.throw(err)
                        handleResult()
                    })
                } else {
                    //同步
                    result = generator.next(result.value)
                    handleResult()
                }
            }
        }