Skip to content

Instantly share code, notes, and snippets.

@SwimmingTiger
Last active June 17, 2018 11:32
Show Gist options
  • Save SwimmingTiger/742aa221bb3a7eb61664a06f48960d71 to your computer and use it in GitHub Desktop.
Save SwimmingTiger/742aa221bb3a7eb61664a06f48960d71 to your computer and use it in GitHub Desktop.
关于生成器函数和async/await的区别与联系的DEMO
function now() {
var d = new Date();
return ('0' + d.getHours()).substr(-2) + ':' + ('0' + d.getMinutes()).substr(-2) + ':' + ('0' + d.getSeconds()).substr(-2);
}
function sleep(t, n) {
return new Promise(function (resolve) {
console.log('begin: ' + n + ' sleep ' + t + 'ms, ' + now());
setTimeout(function () {
console.log('end: ' + n + ' slept ' + t + 'ms, ' + now());
resolve();
}, t);
});
}
async function asyncFunc(n) {
await sleep(2000, n);
await sleep(3000, n);
}
function* gen(n) {
yield sleep(2000, n);
yield sleep(3000, n);
}
function spawn1(g) {
var r = g.next('spawn1');
if (r.value != undefined) {
r.value.then(function () {
spawn1(g);
});
}
}
function spawn2(g) {
var pool = [];
for (var r=g.next('spawn2'); r.value!=undefined; r=g.next('spawn2')) {
pool.push(g.value);
}
Promise.all(pool);
}
spawn1(gen('spawn1'));
spawn2(gen('spawn2'));
asyncFunc('asyncFunc');
@SwimmingTiger
Copy link
Author

SwimmingTiger commented May 28, 2018

http://www.ruanyifeng.com/blog/2015/05/async.html 的回复:

一比较就会发现,async 函数就是将 Generator 函数的星号(*)替换成 async,将 yield 替换成 await,仅此而已。

对此并不十分赞同。async/await 并不是生成器函数和 yield 的替代,而是它们与某种特定的执行器加在一起的替代。而生成器函数的执行器不同,运行效果是完全不一样的。比如星号函数配合用 es6-promise-pool 或者 Promise.all() 实现的执行器可以实现多个 yield 操作的并发执行,这与 async 函数中 await 要做的事情完全不同(await 恰恰就是要等待本次调用的运行结果出来后再进行下次调用,而不是让其与下次调用同时发生)。

比如上面那个例子,输出是这样的:

begin: spawn1 sleep 2000ms, 0:49:50
begin: spawn2 sleep 2000ms, 0:49:50
begin: spawn2 sleep 3000ms, 0:49:50
begin: asyncFunc sleep 2000ms, 0:49:50
end: spawn1 slept 2000ms, 0:49:52
begin: spawn1 sleep 3000ms, 0:49:52
end: spawn2 slept 2000ms, 0:49:52
end: asyncFunc slept 2000ms, 0:49:52
begin: asyncFunc sleep 3000ms, 0:49:52
end: spawn2 slept 3000ms, 0:49:53
end: spawn1 slept 3000ms, 0:49:55
end: asyncFunc slept 3000ms, 0:49:55

可以看出,spawn2 的两个 sleep 是同一时间开始执行的,但是 spawn1 和 asyncFunc 的第二个 sleep 是等到第一个 sleep 执行完成后才开始执行的。

所以在这个例子中,async/await 并不等价于生成器函数 gen,而是等价于生成器函数 gen 和 spawn1 这个特定执行器的结合。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment