有人可以帮我解释一下这两个的执行过程结果为什么不同吗?

发布于 2022-09-12 22:23:46 字数 750 浏览 17 评论 0

首先是这个睡眠函数async function sleep(ms) {
return new Promise(resolve=>{
        setTimeout(resolve,ms)
    })
}

①:for(let i =0;i<2;i++){
    console.log('s');
    await sleep(1000);
    console.log('e')
}

①的结果为image
可见,每次输出的s和e之间都相差了1秒

②:[1,2].forEach(async i=>{
console.log('s');
await sleep(1000);
console.log('e')
})
并且上面这个同时也可以转换为
for(let i =0;i<2;i++){
(async function (){
console.log('s')
await sleep(1000)
console.log('e')
})()
}
②的结果为image
我的第一个疑问为:想不清楚为什么②会先输出了两个s
我的第二个疑问为:②执行了一次sleep之后这个promise就进入了fufilled状态,但是为什么①的promise可以重新进入pending状态并且再次执行呢?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

入画浅相思 2022-09-19 22:23:46
将两次 for 循环给拆开就能理解了。

在这之前定义一个返回时间的变量

var now = {
  valueOf: (function () { return + new Date(); })
};
async function sleep(ms) {
  return new Promise(resolve => {
    console.log(+now);
    setTimeout(resolve, ms)
  })
}
  • 对于第一个部分
// for (let i = 0; i < 2; i++) {
//   console.log(+now, 's');
//   await sleep(1000);
//   console.log(+now, 'e');
// }

{
  console.log(+now, 's');
  await sleep(1000);
  console.log(+now, 'e');
}
{
  console.log(+now, 's');
  await sleep(1000);
  console.log(+now, 'e');
}

运行的结果:
image.png

可以看出这里的执行时同步执行的,前面的代码块执行完了之后后面的代码块才会执行。可以看做是同一个函数同步往下执行代码。

  • 对于第二个部分
// for (let i = 0; i < 2; i++) {
//   (async function () {
//     console.log(+now, 's')
//     await sleep(1000)
//     console.log(+now, 'e')
//   })()
// }

{
  (async function () {
    console.log(+now, 's')
    await sleep(1000)
    console.log(+now, 'e')
  })()
}
{
  (async function () {
    console.log(+now, 's')
    await sleep(1000)
    console.log(+now, 'e')
  })()
}

运行结果:
image.png

可以看出在这里的两个代码块虽然是同步执行的,但执行的是里面的自执行异步函数,两个自执行函数执行后里面的代码又成为了异步,相互之间并不干扰。

第二个疑问:对于sleep函数来说,函数返回的是一个promise对象,即每次调用这个函数之后都会重新生成一个promise对象,因此①和②里面两次执行的sleep函数都会返回一个新的promise,相互之间是不干扰的,因此不存在再次执行的情况。
国粹 2022-09-19 22:23:46

已解决:forEach在循环回调callback的时候,在回调函数的外层是没有使用await的,所以无法延迟,但是callback内部是有await,所以起到了延迟效果。
以下为代码:
[1,2].forEach(async i=>{
console.log('s');
await new Promise(res=>{setTimeout(function(){console.log(Math.random());res(1)},i*1000)})
console.log(i)
})
见结果可见,两个promise都起效了,并且await也起了效果

咽泪装欢 2022-09-19 22:23:46
  • 第一个疑问:因为 forEach 中 sleep 并不会阻塞下一次调用回调函数,而 for 中会
  • 第二个疑问:

    ①的promise可以重新进入pending状态

    这是不可能的,可能你观察有误

  • 关于 for 循环种的 await,如何将每次循环分开,有一个 ES9 中的新特性 for await,可以参考 MDN
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文