繁体   English   中英

async / await + yield / 下一个执行顺序

[英]async / await + yield / next order of execution

提前为长篇道歉! 下面是我正在查看的代码示例和日志输出:

const a = () => new Promise( resolve => {
  setTimeout( () => resolve('result of a()'), 1000);
}); 

const b = () => new Promise( resolve => {
  setTimeout( () => resolve('result of b()'), 500);
});

const c = () => new Promise( resolve => {
  setTimeout( () => resolve('result of c()'), 1100);
});

// async generator function
const MyAsyncGenerator = async function*() {
  yield await a();
  yield await b();
  yield await c();
};

// generator object
const gen = MyAsyncGenerator();

// get 'gen' values
(async () => {
  console.log(await gen.next())
  console.log(await gen.next())
  console.log(await gen.next())
  console.log(await gen.next())
})();

(async () => {
  await Promise.all([a(), b(), c()]).then(res => console.log(res))
})()
{ value: 'result of a()', done: false }
[ 'result of a()', 'result of b()', 'result of c()' ]
{ value: 'result of b()', done: false }
{ value: 'result of c()', done: false }
{ value: undefined, done: true }

我想弄清楚为什么Promise.all([...]).then()是第二个记录的。 这是我最好的解释,但非常感谢任何其他见解:

  1. 由于有两个匿名异步IIFEs(立即调用函数表达式),而第一gen.next()评估的结果a()中, .then()在新的无极方法返回通过Promise.all()被推到微任务队列

  2. 第一次await gen.next()记录到控制台后,调用堆栈为空,因此事件循环将.then()推送到下一个调用堆栈

我最终不确定它是否与任务与微任务队列有关,或者与生成器迭代相关的Promise.all()何时完成。 我的理解是setTimeout()进入任务队列,但是如果我们在生成器迭代下的同一个代码块中包含Promise.all() ,则日志是有序的:

(async () => {
  console.log(await gen.next())
  console.log(await gen.next())
  console.log(await gen.next())
  console.log(await gen.next())
  Promise.all([a(), b(), c()]).then(res => console.log(res))
})();
{ value: 'result of a()', done: false }
{ value: 'result of b()', done: false }
{ value: 'result of c()', done: false }
{ value: undefined, done: true }
[ 'result of a()', 'result of b()', 'result of c()' ]

这是您的程序,其中包含何时发生的时间戳。

@ x ms表示绝对时间(当然是理想化的), T+x ms表示相对时间。 当程序启动时, @ 0 ms事情“同时”发生。

const wait = (value, ms) => new Promise(resolve => setTimeout(() => resolve(value), ms));

const a = () => wait('result of a', 1000);
const b = () => wait('result of b', 600);
const c = () => wait('result of c', 1100);

const MyAsyncGenerator = async function*() {
  yield await a();                             // T+1000 ms   
  yield await b();                             // T+ 600 ms
  yield await c();                             // T+1100 ms
};

const gen = MyAsyncGenerator();                // @    0 ms

(async () => {
  console.log(await gen.next());               // @ 1000 ms
  console.log(await gen.next());               // @ 1600 ms
  console.log(await gen.next());               // @ 2700 ms
  console.log(await gen.next());               // @ 2700 ms
})();                                          // @    0 ms

(async () => {
  await Promise.all([a(), b(), c()])           // @    0 ms
    .then(res => console.log(res));            // @ 1100 ms
})();                                          // @    0 ms

由此很明显Promise.all()将在生成器的第一个和第二个输出之间完成。

请注意,您的第二个函数是无用使用async / await的示例。 await没有任何内容,因此等待没有意义。 最好写成

(() => {
  Promise.all([a(), b(), c()])
    .then(res => console.log(res));
})();

而且由于 IIFE 在这里也没有多大意义,所以它会更好

Promise.all([a(), b(), c()])
  .then(res => console.log(res));

奖金

const gen2 = MyAsyncGenerator();

(async () => {
  console.log(await gen2.next());
  console.log(await gen2.next());
  console.log(await gen2.next());
  console.log(await gen2.next());
})().then(() => {
  Promise.all([a(), b(), c()])
    .then(res => console.log(res));
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM