0
点赞
收藏
分享

微信扫一扫

js 异步函数策略

因为简单实用,所以异步函数很快成为 JavaScript 项目使用最广泛的特性之一。不过,在使用异步 函数时,还是有些问题要注意。

  1. 实现 sleep() 很多人在刚开始学习 JavaScript 时,想找到一个类似 Java 中 Thread.sleep()之类的函数,好在程 序中加入非阻塞的暂停。以前,这个需求基本上都通过 setTimeout()利用 JavaScript 运行时的行为来 实现的。 有了异步函数之后,就不一样了。一个简单的箭头函数就可以实现 sleep():

async function sleep(delay) {
     return new Promise((resolve) => setTimeout(resolve, delay));
}
async function foo() {
const t0 = Date.now();
await sleep(1500); // 暂停约 1500 毫秒 console.log(Date.now() - t0);
   }
   foo();
   // 1502

1. 利用平行执行

如果使用 await 时不留心,则很可能错过平行加速的机会。来看下面的例子,其中顺序等待了 5 个随机的超时:

async function randomDelay(id) {
// 延迟 0~1000 毫秒
const delay = Math.random() * 1000;
return new Promise((resolve) => setTimeout(() => {
        console.log(`${id} finished`);
        resolve();
      }, delay));
}
    async function foo() {
      const t0 = Date.now();
      await randomDelay(0);
      await randomDelay(1);
      await randomDelay(2);
      await randomDelay(3);
      await randomDelay(4);
      console.log(`${Date.now() - t0}ms elapsed`);
} foo();
    // 0 finished
    // 1 finished
    // 2 finished
    // 3 finished
    // 4 finished
    // 877ms elapsed

用一个 for 循环重写,就是:

async function randomDelay(id) {
// 延迟 0~1000 毫秒
const delay = Math.random() * 1000;
return new Promise((resolve) => setTimeout(() => {
    console.log(`${id} finished`);
    resolve();
  }, delay));
}
async function foo() {
const t0 = Date.now();
for (let i = 0; i < 5; ++i) {
    await randomDelay(i);
  }
  console.log(`${Date.now() - t0}ms elapsed`);
}
foo();
// 0 finished
// 1 finished
// 2 finished
// 3 finished
// 4 finished
// 877ms elapsed

就算这些期约之间没有依赖,异步函数也会依次暂停,等待每个超时完成。这样可以保证执行顺序, 7 但总执行时间会变长。

如果顺序不是必需保证的,那么可以先一次性初始化所有期约,然后再分别等待它们的结果。比如:

resolve(); 9 }, delay));
async function randomDelay(id) {
// 延迟 0~1000 毫秒
const delay = Math.random() * 1000;
return new Promise((resolve) => setTimeout(() => {
 setTimeout(console.log, 0, `${id} finished`);
}
async function foo() {
  const t0 = Date.now();
10
 const p0 = randomDelay(0);
const p1 = randomDelay(1);
const p2 = randomDelay(2); 11 const p3 = randomDelay(3);
const p4 = randomDelay(4);
    await p0;
  await p1;
  await p2;
  await p3;
  await p4;
  setTimeout(console.log, 0, `${Date.now() - t0}ms elapsed`);
}
foo();
// 1 finished

举报

相关推荐

0 条评论