【手写 Promise 源码】第十五篇 - 了解 generator 生成器

news2024/12/25 12:16:50

一,前言

上一篇,实现了 promisify 和应用场景介绍,主要涉及以下几个点:

  • promisify 简介和测试;
  • promisify 功能的实现:promisify、promisifyAll;

目前,Promise 部分已基本完成,Promise 仅仅是对异步回到进行了优化,在 Promise 的内部依然还是回调,所以并没有解决“回调地狱”的问题;

最终解决方案还要使用 async/await,async/await 是基于 generator 的语法糖,而为了搞清楚 async/await 的原理,需要先对 generator、co 进行了解;

本篇,介绍 generator 生成器;


二,generator 简介

1,什么是 generator

  • Generator 函数是 ES6 提供的一种异步编程解决方案
  • Generator 函数,可以理解为一个状态机,内部封装多个状态,返回 Iterator 迭代器对象;

2,generator 的特征

  • 星函数:function 关键字与函数名之间有一个星号;
  • yield 表达式(意为“产出”):函数体内部使用 yield 语句,定义不同的内部状态;
  • 暂停执行功能:yield 表达式具有暂停执行的功能,通过 next 方法可以恢复执行;
  • next 方法:每调用一次 next 方法,就会从暂停处继续执行到下一个 yield 表达式为止;

因此,generator 可以把函数的执行权交给外部控制

3,generator 的使用

// 生成器函数: 返回 Iterator 迭代器
function * read(){ // 星函数
  console.log(1)
  yield 1;  // 代码执行遇到 yield 讲终止执行,外部调用 next 后继续
  console.log(2)
  yield 2; 
  console.log(3)
  yield 3; 
}

// 执行生成器函数,返回一个迭代器
let it = read();
it.next();// 走下一步逻辑   执行结果:1
it.next();// 走下一步逻辑   执行结果:2
it.next();// 走下一步逻辑   执行结果:3(此时虽然都走完了,但还需要在 next 一次才能知道)
it.next();// 已全部执行完成

4,generator 的功能分析

根据以上 generator 生成器函数的特性,即:代码的执行可以通过外部函数进行分步控制;
这是一个有限状态机:while(1){switch...case...}


三,generator 实现

1,generator 执行分析

babeljs: babel 能够将低级语法转换成为高级语法;

将之前示例进行转化:

image.png

右侧代码:

"use strict";

var _marked = /*#__PURE__*/regeneratorRuntime.mark(read);

function read() {
  return regeneratorRuntime.wrap(function read$(_context) {
    while (1) {
      switch (_context.prev = _context.next) {
        case 0:
          console.log(1);
          _context.next = 3;
          return 1;

        case 3:
          console.log(2);
          _context.next = 6;
          return 2;

        case 6:
          console.log(3);
          _context.next = 9;
          return 3;

        case 9:
        case "end":
          return _context.stop();
      }
    }
  }, _marked);
}

var it = read();
it.next();
it.next();
it.next();
it.next();

代码分析:

  • while(1):表示有限状态机,内部的switch...case...会被执行多次;
  • _context.prev:是代码的执行指针,会根据指针逐层地向下依次执行;
  • 第一次_context.next = 0后,_context.prev被赋值为 0, 执行 case 0 的逻辑;执行完成后_context.next = 2,继续再执行执行 case 2 的逻辑…直至最后调用 _context.stop()完成;

四,结尾

本篇,主要介绍了 generator 生成器函数的使用和实现原理,主要涉及以下几个点:

  • generator 简介:特性、用法、功能分析;
  • generator 实现原理分析;

下篇,继续介绍 co 库:自动执行 Generator 生成器函数;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/194702.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

FPGA实现图像任意位置显示,串口协议控制显示位置,提供工程源码和技术支持

目录1、图像任意位置显示理论基础2、设计思路和架构3、OV5640图像采集4、图像DDR3三帧缓存5、图像任意位置输出显示6、串口协议控制显示位置7、vivado工程介绍8、上板调试验证9、福利:工程源码获取1、图像任意位置显示理论基础 图像任意位置显示指的是在显示屏上的…

Linux新手渣渣上路史

时至2022年,IT行业的迅速发展大家也有目共睹,IT行业在社会的发展中起着举足轻重的作用。其中一角Linux系统,从诞生到开源,再到现在受大众的欢迎,是一个很好的例子。Linux和windows类似,是一个操作系统&…

java 微服务高级之分布式事务 Seata框架 CAP定理 BASE理论 XA模式 AT模式 TCC模式 SAGA模式

分布式事务问题 1.1.本地事务 1.2.分布式事务 一旦有一个失败了,其他两个不知情失败的情况,还是执行并成功 在分布式系统下,一个业务跨越多个服务或数据源,每个服务都是一个分支事务,要保证所有分支事务最终状态一致…

【JavaEE】线程安全的集合类

引言 在Java标准库中,大部分集合类都是线程不安全的。Vector(比ArrayList多了同步化机制就变得线程安全了);Stack(继承Vector);Hashtable(只比Hashmap多了线程安全);以Concurrent开头的集合类:ConcurrentHashMap、Con…

Echarts 用图形纹理来填充颜色(color - pattern)

第006个点击查看专栏目录在上一篇文章中已经讲过 ECharts线性渐变色示例演示(2种渐变方式),这个示例的颜色使用纹理来做填充,纹理填充: pattern color:{ //纹理填充 image: patternImg, repeat: ‘repeat’ } 示例效果…

禾川HCQ ModBUS+485主从站调试

硬件,485转usb,如果主站是plc,不需要这个线,我现在主站是电脑,调试用。 HCQ0 禾川控制器。 软件 modbus tools 调试软件,自行下载吧,社区传不上去。 硬件连接时注意交叉连接,HCQ0 A端…

MATLAB 逻辑数组

✅作者简介:人工智能专业本科在读,喜欢计算机与编程,写博客记录自己的学习历程。 🍎个人主页:小嗷犬的个人主页 🍊个人网站:小嗷犬的技术小站 🥭个人信条:为天地立心&…

Java⽇志框架学习笔记

目录 1.⽇志概述 1.1 ⽇志是⽤来做什么的? 1.2 为什么要⽤到⽇志框架? 1.3 现有的⽇志框架有哪些? 1.4 ⽇志⻔⾯技术 2.logback 2.1 logback介绍 2.1.1 logback 模块 2.1.2 logback 组件 2.1.3 logback 配置 2.1.4 logback.xml 配…

2023网络爬虫 -- 获取动态数据

一、网站的正常界面1、网址https://movie.douban.com/typerank?type_name%E5%8A%A8%E4%BD%9C%E7%89%87&type5&interval_id100:90&action2、正常的页面二、爬取数据1、源代码import requests头{"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64…

首屏加载速度慢怎么解决?

一、什么是首屏加载 首屏时间(First Contentful Paint),指的是浏览器从响应用户输入网址地址,到首屏内容渲染完成的时间,此时整个网页不一定要全部渲染完成,但需要展示当前视窗需要的内容 首屏加载可以说是…

分享156个ASP源码,总有一款适合您

ASP源码 分享156个ASP源码,总有一款适合您 下面是文件的名字,我放了一些图片,文章里不是所有的图主要是放不下..., 156个ASP源码下载链接:https://pan.baidu.com/s/1Mc-zWjUyk9Lx8TXv5cvZTg?pwds2qi 提取码&#x…

Office 365用户登录审核

黑客访问端点设备,以窃取公司特定数据、员工个人数据或任何其他可能对他们有任何用处的有价值的信息。 为了帮助您防止这种攻击,我们编写了一个参数列表,可以帮助您识别异常日志,这通常是攻击的第一个标志。异常登录活动是安全漏洞…

Vue使用ElementUI的确认框进行删除操作(包含前后端代码)

前言 今天做自己项目的时候,有一个删除的业务,正好遇到了确认框,在此纪念一下。 这里我是使用的ElementUI的确认框! 首先ElementUI的确认框是这么说明的: 从场景上说,MessageBox 的作用是美化系统自带的 …

Java程序员跳槽,三面全过,面试官:你这样的,我们招不起

程序员小李在沿海城市工作了8年,那里涨幅飞快的房价限制了程序员小李在一线城市安家的想法,再加上突然发生的疫情暴露了远在他乡工作的不便,在种种因素下,程序员小李决定回家工作。 既然已经下定决心告别一线城市回家乡发展&…

数据分析面试-sql练习

SQL汇总1. SQL执行顺序2. 开窗函数3. 经典SQL题3.0 数据准备3.1 ☆ 查询‘01’课程比‘02’课程成绩高的学生3.2 查询平均成绩大于等于60分的同学的学生编号和学生姓名和平均成绩3.3 查询在SC表存在成绩的学生信息3.4 查询所有同学的学生编号、学生姓名、选课总数、所有课程的总…

Github每日精选(第96期):微软的机器学习课程ML-For-Beginners

12 周,26 节课,52 道测验,适合所有人的经典机器学习。 添加链接描述 初学者机器学习 - 课程 Microsoft 的 Azure Cloud Advocates 很高兴提供为期 12 周、26 节课的全部关于机器学习的课程。在本课程中,您将了解有时称为经典机器…

【C++】面向对象:继承

🐱作者:傻响 🐱专栏:《C语法》 🔥格言:你只管努力,剩下的交给时间! 目录 C中的继承 1.继承的概念及定义 1.1继承的概念 1.2 继承定义 1.3 继承关系和访问限定符 1.4 继承基类成…

ES6中扩展运算符的9种用法

1. 拷贝数组对象 const years [2018, 2019, 2020, 2021]; const copyYears [...years];console.log(copyYears); // [ 2018, 2019, 2020, 2021 ]扩展运算符拷贝数组,只有第一层是深拷贝,即对一维数组使用扩展运算符拷贝就属于深拷贝 2. 合并数组 先…

c++入门语法

文章目录1. 命名空间1.1 域的介绍1.2 命名空间的定义1.3 命名空间的三种使用方式2. C输入&&输出3. 缺省参数3.1 概念3.2 缺省参数分类4. 函数重载4.1 概念4.2 C支持函数重载的原理--名字修饰5. 引用5.1 概念5.2 特性5.3 常引用5.4 使用场景5.5 指针和引用的区别6. 内联…

OpenCV-PyQT项目实战(3)信号与槽机制

欢迎关注『OpenCV-PyQT项目实战 Youcans』系列,持续更新中 OpenCV-PyQT项目实战(1)安装与环境配置 OpenCV-PyQT项目实战(2)QtDesigner 和 PyUIC 快速入门 OpenCV-PyQT项目实战(3)信号与槽机制 …