当前位置: 首页 > article >正文

js中generator详解

什么是 Generator

Generator 是 ES6 提供的一种异步编程解决方案。可以把它理解为一种状态管理器。
调用 Generator 函数之后,它只是进行实例化工作,并没有真实的执行内部代码,所以不会像其他函数一样返回函数结果,而是会返回一个指向内部状态的指针对象,也就是所说的迭代器对象,需要继续调用 next 方法,next 方法会返回一个 iterate,以确保后续代码执行。
Generator 特性:

  1. function 关键字与函数名之间需要有一个星号 *;
  2. 调用后不会立即执行函数结果,而是返回一个遍历器对象 iterator ;
  3. Generator 内部需要使用 yield 来定义暂停状态;

next

但是 next 方法遇到 yield 就会停止, 一个 next 只能执行一个 yield 之前的内容,直到下一个 yield 为止。如下:

function* gen() {
	console.log('我在gen函数内部', 1)
    return 1
}
const iterator = gen() //不执行
console.log(iterator.next()) // 执行, 打印{value:1,done:true}

yield

什么是 yield 呢?可以理解为暂停,简单来说 yield + next ~= return ,但是与return 不一样的是, return 是停止执行后面的方法,而 yield 只是停止当前的 next,直到下一个 next 调用的时候,继续执行。如下:

  <script>
    function* gen() {
      yield '我是第一个返回值'
      yield '我是第二个返回值'
      yield '我是第三个返回值'
    }
    let res = gen()
    console.log(res.next()); //value: 我是第一个返回值
    console.log(res.next()); //value: 我是第二个返回值
   	console.log(res.next()); //value: 我是第三个返回
console.log(res.next()); //value: undefined, done: true
  </script

如果 yield 放在了等号的右边,同样也会停止执行后续代码,不会执行等于操作,因为在执行等号之前就已经停止,所以返回值依旧是通过next取到,直到下一个next出现,才会继续之前的操作,如下:

function* gen(num) {
    let r1 = yield 1
    console.log('r1', r1);

    let r2 = yield 2
    console.log('r2', r2);

    let r3 = yield 3
    console.log('r3', r3);

}
const iterator = gen()
console.log(iterator.next())
console.log(iterator.next())
console.log(iterator.next())
console.log(iterator.next()) 

async await

其实之所以我们说 Generator 能够把异步变同步,是因为 Generator 函数中我们只需要写同步代码就可以,真正执行异步操作的是迭代器对象。在复杂的业务逻辑中,大量使用迭代器对象来执行异步操作,会使得代码变得很不优雅,于是 ES7 中就推出了 async await 方案来实现异步变同步。 async await 可以理解为一个自执行 Generator 函数,真正的异步操作被封装在底层,这样的写法,使得代码变优雅了很多。如下:

function requestFn () {
	return new Promise ((resolve)=>{
		setTimeout(()=>{
			resolve(1)
		}, 500)
	}
}
functio async gen(num) {
    console.log('r1')
    let r1 = await requestFn()
    console.log('r2')
	return r1
}

gen().then(res=>{
	console.log('r3', res)
}
// r1  500ms  r2  r3 1

http://www.kler.cn/a/4439.html

相关文章:

  • Flink链接Kafka
  • --- 多线程编程 基本用法 java ---
  • 【大模型系列篇】数字人音唇同步模型——腾讯开源MuseTalk
  • 医学图像分割半监督学习记录
  • vscode 扩展Cline、Continue的差别?
  • mapbox进阶,添加绘图控件
  • C++之引用
  • 类ChatGPT平台推荐【国内访问ChatGPT4】
  • eNSP 本地AAA配置实验
  • <class ‘sensor_msgs.msg._Image.Image‘>原理
  • Apache iotdb-web-workbench 认证绕过漏洞 CVE-2023-24829
  • Exception 和 Error
  • Pytorch梯度下降——up主:刘二大人《PyTorch深度学习实践》
  • 【HTB】Responder思路——Responder抓取ntlmhash、远程文件包含、远程代码执行、evil-winrm连接
  • 文件操作练习
  • Python中关于字典和Counter()的两点区别
  • PCB模块化设计06——HDMI接口PCB布局布线设计规范
  • 推荐5款精致小巧无广告的软件
  • 【深度学习】常见优化算法的NumPy和PyTorch实现
  • WebRTC技术分析
  • 【C语言蓝桥杯每日一题】——跑步锻炼
  • SpringBoot启动流程源码分析一、入口参数研究和创建对象
  • python基础篇:什么是装饰器?装饰器有什么用?
  • 【设计模式】单例模式
  • 蓝桥杯冲刺 - week1
  • ESP IDF docker 使用方法