请教关于 JavaScript 里 Generator 的问题

2018-11-20 09:20:48 +08:00
 frederick036

You Don't Know JS 介绍 Generator 的第四章 里有一个练习:

var a = 1;
var b = 2;

function *foo() {
	a++;
	yield;
	b = b * a;
	a = (yield b) + 3;
}

function *bar() {
	b--;
	yield;
	a = (yield 8) + b;
	b = a * (yield 2);
}

function step(gen) {
	var it = gen();
	var last;

	return function() {
		// whatever is `yield`ed out, just
		// send it right back in the next time!
		last = it.next( last ).value;
	};
}

var s1 = step( foo );
var s2 = step( bar );

s2();		// b--;
s2();		// yield 8
s1();		// a++;
s2();		// a = 8 + b;
			// yield 2
s1();		// b = b * a;
			// yield b
s1();		// a = b + 3;
s2();		// b = a * 2;

最后运行的结果是,

console.log( a, b );	// 12 18

请问这个最后的 b 为什么是 18 而不是 24

我自己先算了一遍,然后在 Chrome Console 里运行了一遍,每一步运行后 ab 的结果都是正确的,只有最后一步的 b 不正确。

我自己计算的是:最后一步的 s2() 之前,a = 12, b = 9;(根据 console 运行的结果,到这里都是正确的)而最后一步 s2() 所做的就是把 a 的值(12)乘以 22*12 = 24) 赋值给 b,因此得到 b 最后的结果是 24

正确答案是 18 我实在不理解。各位有何高见?

1737 次点击
所在节点    问与答
8 条回复
tecton
2018-11-20 10:08:27 +08:00
我的推测:最后的 s2 调用时上下文中 a=9, b=1。因此 b = a * (yield 2)会得到 b=9*2=18。
jin5354
2018-11-20 10:32:06 +08:00
生成器执行时,会执行到**出现 yield 的位置为止**暂停
在执行第三次 s2 时,b = a * (yield 2) ,到 yield 暂停,即 a * 这部分已执行,a 固化在当时状态了
执行第四次 s2 时,只是把 2 填进去而已,a 不会重新取值了
不然你把那行改成 b = (yield 2) * a 试试?
sogood
2018-11-20 10:36:22 +08:00
不推荐用 Generator,难学难懂,用 async/await 替代。
valentin508
2018-11-20 10:38:46 +08:00
同意楼上…现在除了在 redux-saga 里面稍微用下其他部分都是用 async/await+promise 来做异步
jin5354
2018-11-20 10:44:53 +08:00
Generator 不是用来做异步的,是用来做生成器的;之前做异步只是巧合而已。
maichael
2018-11-20 10:57:48 +08:00
```javascript
function *bar() {
b--;
yield;
a = (yield 8) + b;
console.log(a, 'a')
b = a * (yield 2);
}
```

看这个就知道了。
maichael
2018-11-20 11:00:27 +08:00
发错

```javascript
function *bar() {
b--;
yield;
a = (yield 8) + b;
console.log(yield a, 'a')
}
```
Jasonwxy
2018-11-20 11:32:00 +08:00

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/509476

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX