ES6学习Generator 函数(生成器)(八)

这里写目录标题

一、基本概念

  • Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同,Generator 函数有多种理解角度。
  • 语法上,首先可以把它理解成,Generator 函数是一个状态机,封装了多个内部状态。
    执行 Generator 函数会返回一个遍历器对象,也就是说,Generator 函数除了状态机,还是一个遍历器对象生成函数。返回的遍历器对象,可以依次遍历 Generator 函数内部的每一个状态。
  • 形式上,Generator函数是一个普通函数,但是有两个特征。一是, function 关键字与函数名之间有一个星号;二是,函数体内部使用 yield 表达式,定义不同的内部状态( yield 在英语里的意思就是"产出")。
  • 由于 Generator 函数返回的遍历器对象,只有调用 next 方法才会遍历下一个内部状态,所以其实提供了一种可以暂停执行的函数。yield表达式就是暂停标志。

二、代码

js 复制代码
        //生成器函数:function关键字和函数名之间有一个*
        function* add(){
            console.log('start');
            let x = yield '2';
            console.log('one:'+2);
            let y = yield '3';
            console.log('two:'+y);
            return x+y;

        }
        // 返回一个遍历器对象
        let fn=add();
        // next() 恢复执行标志
        console.log(fn.next());
        // 当 next() 传入参数时,该参数就会被当作上一个 yield 表达式的返回值 ,即 x = 20, y = 3
        console.log(fn.next(20));// one:20     {value: '3', done: false}
        console.log(fn.next(30));// two:30     {value: '50', done: true}
  • 使用场景:为不具备 Iterator 接口的对象提供了遍历操作
  • 利用for...of循环,可以写出遍历任意对象(object)的方法。原生的 JavaScript 对象没有遍历接口(不具备 Symbol.iterator方法),无法使用for...of循环,通过 Generator 函数为它加上这个接口,即将 Generator 函数加到对象的Symbol.iterator属性上面,就可以用了。
js 复制代码
        //Gemerator 生成器函数
        function* objectEntries(obj) {
            //获取对象的所有key保存到数组
            const propKeys = Object.keys(obj);
            for (const propkey of propKeys) {
                yield [propkey, obj[propkey]]
            }

        }

        const obj = {
            book: 'ES6学习',
            price: 18
        }
        // 把 Generator 生成器函数赋值给对象的Symbol.iterator属性, 为该对象加上遍历器接口
        obj[Symbol.iterator] = objectEntries;
        console.log(obj);//{book: 'ES6学习', price: 18, Symbol(Symbol.iterator):
        // objectEntries(obj) 等价于 obj[Symbol.iterator](obj) 
        for (let [key, value] of objectEntries(obj)) {
            console.log(`${key}: $value`);
        }

三、Generator 函数的异步应用

Generator 函数在ajax请求的异步应用,让异步代码同步化

Generator 函数在加载页面的异步应用

js 复制代码
       //Generator 函数在加载页面的异步应用
       // 1.加载 Loading...页面
       // 2.数据加载完成...(异步操作)
       // 3.Loading 关闭掉
       function loadUI() {
           console.log('加载 Loading...页面');
       }

       function showData() {
           // 模拟数据加载异步操作
           setTimeout(() => {
               console.log('数据加载完成');
           }, 1000);
       }

       function hideUI() {
           console.log('隐藏 Loading...页面');
       }

       loadUI();
       showData();
       hideUI();

上述代码执行后效果:

加载 Loading...页面
隐藏 Loading...页面
数据加载完成

实际需求是加载数据完成后才关闭页面,但由于三个函数函数是同步执行的,数据加载需要时间,在数据未加载完成时,就已经隐藏loading页面。通过 Generator 函数可以解决这个问题。

js 复制代码
         function* load(){
            loadUI();
            yield showData();     
            hideUI()
        }

        const itLoad = load();
        itLoad.next();

        function loadUI() {
            console.log('加载 Loading...页面');
        }

        function showData() {
            // 模拟数据加载异步操作
            setTimeout(() => {
                console.log('数据加载完成');
                itLoad.next();
            }, 1000);
        }

        function hideUI() {
            console.log('隐藏 Loading...页面');
        }

三级目录

相关推荐
CodeToGym4 小时前
使用 Vite 和 Redux Toolkit 创建 React 项目
前端·javascript·react.js·redux
Cachel wood5 小时前
Vue.js前端框架教程8:Vue消息提示ElMessage和ElMessageBox
linux·前端·javascript·vue.js·前端框架·ecmascript
小屁不止是运维7 小时前
麒麟操作系统服务架构保姆级教程(二)ssh远程连接
linux·运维·服务器·学习·架构·ssh
孤留光乩7 小时前
从零搭建纯前端飞机大战游戏(附源码)
前端·javascript·游戏·html·css3
伊泽瑞尔.7 小时前
el-tabs标签过多
前端·javascript·vue.js
2401_854391088 小时前
智能挂号系统设计典范:SSM 结合 Vue 在医院的应用实现
前端·javascript·vue.js
觉醒的程序猿8 小时前
vue2设置拖拽选中时间区域
开发语言·前端·javascript
follycat8 小时前
bestphp‘s revenge
学习·web安全
职业考试资料墙8 小时前
二级建造师考试题库及答案
学习·考试·题库