首页 > 其他分享 >js 异步函数策略

js 异步函数策略

时间:2024-01-20 19:01:33浏览次数:19  
标签:异步 resolve const 函数 await js finished randomDelay foo

因为简单实用,所以异步函数很快成为 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

标签:异步,resolve,const,函数,await,js,finished,randomDelay,foo
From: https://blog.51cto.com/u_16237074/9346040

相关文章

  • js 停止和恢复执行
    使用await关键字之后的区别其实比看上去的还要微妙一些。比如,下面的例子中按顺序调用了3个函数,但它们的输出结果顺序是相反的:asyncfunctionfoo(){console.log(awaitPromise.resolve('foo'));}8asyncfunctionbar(){console.log(await'bar');}asyncfun......
  • js await 的限制
    等待会抛出错误的同步操作,会返回拒绝的期约:```jsasyncfunctionfoo(){console.log(1);await(()=>{throw3;})();}//给返回的期约添加一个拒绝处理程序foo().catch(console.log);console.log(2);//1//2//3```如前面的例子所示,单独的Promise.reject()不会被异步函......
  • js 异步函数的返回值
    函数可以得到它返回的期约:asyncfunctionfoo(){console.log(1);return3;}//给返回的期约添加一个解决处理程序foo().then(console.log);console.log(2);//1//2//3当然,直接返回一个期约对象也是一样的:asyncfunctionfoo(){console.log(1);returnProm......
  • 池和异步回调机制
    池【1】概念池是用来保证计算机硬件安全的情况下,最大限度的利用计算机资源,降低了程序的运行效率,但是保证了计算机硬件的安全池(Pool)的概念在计算机科学和软件工程中常被用于资源管理,尤其是在多线程或并发编程中。池是一种管理和优化资源分配的机制,它事先分配一定数量的资源(......
  • std::declval 元函数
    declval用于非求值上下文中declval原形:template<typename_Tp>autodeclval()noexcept->decltype(__declval<_Tp>(0)){static_assert(__declval_protector<_Tp>::__stop, "declval()mustnotbeused!");return__declval&l......
  • Python中的回调函数
    先来看一个程序:deff1():print(2)return1deff2(a):print(3)returnaprint(f2(f1()))这个程序,在调用时,f2会先等待f1调用完毕,返回1之后,再进行调用,所以会输出2、3、1,但是若这样改写程序deff1():print(2)return1deff2(f):prin......
  • 日期函数——来源网络,方便查阅
    DateUtils时间单元,非常有用。记得引用这个单元,不然不能用。CompareDate比较两个日期时间值日期部分的大小CompareDateTime比较两个日期时间值的大小CompareTime比较两个日期时间值时间部分的大小DateOf去除日期时间值的时间部分DateTimeToJulianDate转换日期时间值为儒略日......
  • 积性函数学习笔记
    积性函数定义积性函数:\(f(x)\)满足\(\forall\gcd(a,b)=1,f(ab)=f(a)f(b)\)若没有\(\gcd(a,b)=1\)的性质,则为完全积性函数。性质性质1:\(f(x),g(x)\)是积性函数\(\implies\)\(f\timesg\)是积性函数,\(f\divg\)是积性函数证明略。性质2:狄利克雷(Dirichlet)卷积\(......
  • MySQL中的加密函数
    本文简单介绍MySQL中的加密函数。MySQL提供了多种加密函数,以下是一些常用的:PASSWORD(str):用于密码加密,通常用于创建用户时对密码进行加密。MD5(str):生成一个128位的加密串,返回一个32位的16进制数。SHA1(str):生成一个160位的加密串,返回一个40位的16进制数。ENCODE(str......
  • Visual Studio Code 解决JSON中不允许注释?
    1.使用vscode打开json文件后,一些注释显示如图所示,有红色波浪线,影响阅读 2.悬浮在波浪线报错信息,会弹出提示ViewProblem,提示问题是:json文件中不允许注释 3.下面图片表示json文件中不允许注释 4.点击底部工具栏的JSON 5.弹出的窗口中输入jsonwithComments,找......