在接触到生成器之初对generator.next()和yield之间的关系是什么没有办法理解透彻,直到看到两句话:
- Generator 函数是一个状态机,封装了多个内部状态 — Generator 函数的语法
- 子程序(函数)就是协程的一种特例 — 协程
Generator 函数是一个状态机,封装了多个内部状态
function* helloworld() {
yield 'hello'
yield 'world'
}
const ge = helloworld()
ge.next()
ge.next()
Generator helloworld中通过两个yield产出了两个状态,分别是’hello’和’world’,Generator外部获取这两个状态的方式是调用ge对象的next()方法。
第一次调用next方法获取第一个状态"hello" ,第二次调用next方法获取第二个状态"world" 。
其中yield 表达式和next 方法均用来切换执行上下文,其中next方法将执行上下文从Generator函数外部切换到内部,而yield将执行上下文从Generator函数内部切换到函数外部。除了切换上下文next还将入参传入了函数内部作为yield表达式的返回值,同理,yield也将表达式的值传递给了函数外部。
function* helloworld() {
const a = yield 1
console.log(a)
yield 3
}
const ge = helloworld()
const val1 = ge.next()
console.log(val1.value)
const val3 = ge.next(2)
console.log(val3.value)
子程序(函数)就是协程的一种特例
function* helloworld() {
const a = yield 1
console.log(a)
yield 3
}
const ge = helloworld()
const val1 = ge.next()
console.log(val1.value)
const val3 = ge.next(2)
console.log(val3.value)
在例子里可以将next()可以当做在执行函数,而yield作为return来看的就会好理解很多。
- 第一个
next() 从函数第一行开始执行,到 yield 1 结束执行,返回值1到函数外部。 - 第二个
next(2) ,从第一个yield 1 处开始执行,用2 作为yield 1 的返回值,换句话说就是函数开始执行的入参,入参被const a 接收,到yield 3 返回值3
所以说子程序(函数)就是协程的一种特例。
函数也是封装了状态,通过调用函数获取对应状态,只是这个状态只有一个,函数只能被执行一次,retrun之后无法再继续return之后的语句执行,而generator提供了继续执行中断上下文执行的能力。
|