第 130 题:输出以下代码执行结果,大致时间就好(不同于上题)

发布于 2022-06-01 08:59:23 字数 239 浏览 977 评论 10

function wait() {
  return new Promise(resolve =>
    setTimeout(resolve, 10 * 1000)
  )
}

async function main() {
  console.time();
  await wait();
  await wait();
  await wait();
  console.timeEnd();
}
main();

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

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

发布评论

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

评论(10

踏月而来 2022-05-04 13:48:44
/**
 *  一切将异步貌似写为同步的写法,其实本质上都是被转换为了回调函数。
 *  首先明白一个概念,这个 async main函数返回的Promise,什么时候被resolve,就是当整段函数代码执行完返回undefined或者中途抛错。
 * await 究竟做了什么,?
 * ````
 * await foo();
 * 执行代码...
 * ```
 * 类似于Promise.resolve(foo()).then(()=>{ 执行代码... })
 **/

// 举一个简单的例子
async function foo() {
  console.log(1);
  await foo1();
  console.log(2);
}

// 等价效果
function foo() {
  return new Promise((resolve, reject) => {
    console.log(1);
    Promise.resolve(foo1()).then(() => {
      console.log(2);
    });
  });
}

// 分析题主的demo
function wait() {
  return new Promise(resolve => setTimeout(resolve, 10 * 1000));
}

async function main() {
  console.time();
  await wait();
  await wait();
  await wait();
  console.timeEnd();
}
main();

// 等价效果
function main() {
  return new Promise((resolve, reject) => {
    console.time();
    Promise.resolve(
      new Promise(resolve => setTimeout(resolve, 10 * 1000))
    ).then(() => {
      Promise.resolve(
        new Promise(resolve => setTimeout(resolve, 10 * 1000))
      ).then(() => {
        Promise.resolve(
          new Promise(resolve => setTimeout(resolve, 10 * 1000))
        ).then(() => {
          console.timeEnd();
        });
      });
    });
  });
}

/**
 * 可以看得出来,10s的定时器的回调按顺序执行,加起来就有30s了
 * 至于为什么会比30s多一些,这个要考虑,settimeOut是宏任务,Promise是微任务,
 * 在第一个事件循环,实例化promise跟执行代码都进行耗时,假设20ms之类的
 * 这个时候会执行到第一个Promise的resolve回调,执行第一个settimeout,定时器计时才开始,等10s计时完毕,才添加进去事件队列,进入下一次事件循环,pop事件跟执行回调,
 * 并且这个过程还会有v8的垃圾回收,触发新生代的From To垃圾回收跟老生代的增量标记,这部分也是需要耗时的,假设耗时80ms,所以一次settimeout下来,耗费的时间是多于10m的
 * 总的就是30s多一些
 */

function wait() {
return new Promise(resolve =>
setTimeout(resolve, 10 * 1000)
)
}

async function main() {
console.time();
let a = wait();
let b = wait();
let c = wait();
await a;
await b;
await c;
console.timeEnd();
}
main();

这个怎么解释???

最﹫后的乘客 2022-05-04 13:48:23

30s多一点,因为js执行不会立刻执行setTimeout,而是有等待其他代码的执行。

倾城月光淡如水﹏ 2022-05-04 13:35:30

normal

function wait() {
  return new Promise(resolve =>
    setTimeout(resolve, 10 * 1000)
  )
}

async function main() {
  console.time();
  await wait();
  await wait();
  await wait();
  console.timeEnd();
}
main();
// Promise {<pending>}
// default: 30001.47412109375ms

better

function wait() {
  return new Promise(resolve =>
    setTimeout(resolve, 10 * 1000)
  )
}

async function main() {
  console.time();
  let a = wait();
  let b = wait();
  let c = wait();
  await a;
  await b;
  await c;
  console.timeEnd();
}
main();
// Promise {<pending>}
//  default: 10004.033203125ms
清音悠歌 2022-05-03 09:25:55
/**
 *  一切将异步貌似写为同步的写法,其实本质上都是被转换为了回调函数。
 *  首先明白一个概念,这个 async main函数返回的Promise,什么时候被resolve,就是当整段函数代码执行完返回undefined或者中途抛错。
 * await 究竟做了什么,?
 * ````
 * await foo();
 * 执行代码...
 * ```
 * 类似于Promise.resolve(foo()).then(()=>{ 执行代码... })
 **/

// 举一个简单的例子
async function foo() {
  console.log(1);
  await foo1();
  console.log(2);
}

// 等价效果
function foo() {
  return new Promise((resolve, reject) => {
    console.log(1);
    Promise.resolve(foo1()).then(() => {
      console.log(2);
    });
  });
}

// 分析题主的demo
function wait() {
  return new Promise(resolve => setTimeout(resolve, 10 * 1000));
}

async function main() {
  console.time();
  await wait();
  await wait();
  await wait();
  console.timeEnd();
}
main();

// 等价效果
function main() {
  return new Promise((resolve, reject) => {
    console.time();
    Promise.resolve(
      new Promise(resolve => setTimeout(resolve, 10 * 1000))
    ).then(() => {
      Promise.resolve(
        new Promise(resolve => setTimeout(resolve, 10 * 1000))
      ).then(() => {
        Promise.resolve(
          new Promise(resolve => setTimeout(resolve, 10 * 1000))
        ).then(() => {
          console.timeEnd();
        });
      });
    });
  });
}

/**
 * 可以看得出来,10s的定时器的回调按顺序执行,加起来就有30s了
 * 至于为什么会比30s多一些,这个要考虑,settimeOut是宏任务,Promise是微任务,
 * 在第一个事件循环,实例化promise跟执行代码都进行耗时,假设20ms之类的
 * 这个时候会执行到第一个Promise的resolve回调,执行第一个settimeout,定时器计时才开始,等10s计时完毕,才添加进去事件队列,进入下一次事件循环,pop事件跟执行回调,
 * 并且这个过程还会有v8的垃圾回收,触发新生代的From To垃圾回收跟老生代的增量标记,这部分也是需要耗时的,假设耗时80ms,所以一次settimeout下来,耗费的时间是多于10m的
 * 总的就是30s多一些
 */

小梨窩很甜 2022-05-03 05:14:42

这道题可以这样看执行顺序和每一步消耗的时间:

function wait() {
  return new Promise(resolve =>
    setTimeout(resolve, 10 * 1000)
  )
}

async function main() {
  console.time('ALL:');
  console.time('A:')
  await wait();
  console.timeEnd('A:');
  console.time('B:');
  await wait();
  console.timeEnd('B:');
  console.time('C:');
  await wait();
  console.timeEnd('C:');
  console.timeEnd('ALL:');
}
main();

打印的结果为:
A:: 10002.716064453125ms
B:: 10005.09814453125ms
C:: 10004.77197265625ms
ALL:: 30013.97412109375ms

那伤。 2022-05-03 04:15:21

先说结果,大概30秒多点,30秒是因为每个等待10秒,同步执行。
其实还有一个变种:

function wait() {
  return new Promise(resolve =>
    setTimeout(resolve, 10 * 1000)
  )
}

async function main() {
  console.time();
  let a = wait();
  let b = wait();
  let c = wait();
  await a;
  await b;
  await c;
  console.timeEnd();
}
main();

这个的运行时间是10s多一点,这是因为:a,b,c的异步请求会按顺序发起。而这个过程是不需要互相依赖等待的。等到wait的时候,其实是比较那个异步耗时最多。就会等待最长。最长的耗时就是整体的耗时。

如果在业务中,两个异步没有依赖关系。应该是后面这种写法。

盗心人 2022-04-30 17:36:47

30s多一点
调用wait函数时加上了await修饰符,导致主流程的执行必须要等待wait函数执行完才会陆续执行后续函数,相当于 await wait() => promise -> wait() -> resolve()
但是wait函数本身又写了一个promise,整个promise会setTimeout才resolve,相当于本身wait函数 => promise -> setTimeout(resolve)
那么整个串起来,流程有点类似下面这样子,promise的嵌套,只有等内部wait函数的promise -> resolve之后,才会将外部的promise -> resolve掉。然后再去执行下一个wait函数。
main -> wait -> promise -> (promise -> setTimeout(resolve))(resolve)
为啥要30s多一点,额,写入微任务队列,微任务队列里再写入任务队列,都是需要时间。

老街孤人﹏ 2022-04-30 07:03:19

30s多点

落花浅忆 2022-04-29 23:30:48

30s

~没有更多了~

关于作者

情话难免假

暂无简介

文章
评论
26 人气
更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文