Promise与Web Locks绝配

大家好,我是CC,在这里欢迎大家的到来~

背景

为什么会有这样的感慨呢?

是这样,最近业务上对批量审核的功能进行了优化,由原先的循环挨个请求改成了并发模式,提高了效率;但是紧接着上线后发现在一个特殊业务上批量审核后总有漏掉的,排查发现是该业务下有“Group”的概念,当批量审核同“Group”下的内容时并发导致资源抢占,而且超时时间设置较短,在事务回滚后部分审核没有完成。

问题找到了如何解决呢。当然可以让后端同事处理,但是细想后前端可以三行代码轻松解决这个问题。

于是就发现 Promise 与 Web Locks 配合的妙处。

Promise

异步任务

JavaScript 的本质上是单线程的,因此在任何时刻,只有一个任务会被执行,尽管控制权可以在不同的 Promise 之间切换,从而使 Promise 的执行看起来是并发的。

在 JavaScript 中,并行执行只能通过 worker 线程实现。

如果一个 Promise 已经被兑现或拒绝,即不再处于待定状态,那么则称之为已敲定(settled)

并发方法

Promise.all() - 在所有传入的 Promise 都被兑现时兑现;在任意一个 Promise 被拒绝时拒绝。

Promise.allSettled() - 在所有的 Promise 都被敲定时兑现。

Promise.any() - 在任意一个 Promise 被兑现时兑现;仅在所有的 Promise 都被拒绝时才会拒绝。

Promise.race() - 在任意一个 Promise 被敲定时敲定。换句话说,在任意一个 Promise 被兑现时兑现;在任意一个的 Promise 被拒绝时拒绝。

其他常用方法

Promise.resolve() - 返回一个新的 Promise 对象,该对象以给定的原因拒绝。

Promise.reject() - 返回一个新的 Promise 对象,该对象以给定的值兑现。

Web Locks

之前文章有讲述过,这里跳转复习下吧。

Web Locks

结合使用场景

现在我们实现下开头说的场景需求:

// 伪代码
const taskFns = tasks.map((task) => {
  return () => {

    return new Promise((resolve, reject) => {
      const requestId = task.groupId === "" ? `updateStatus-${task?.id}` : `updateStatus-${task.groupId}`;
      // 三行代码搞定
      navigator.locks.request(requestId, async() => {
        try {
          // 其他同步/异步操作
        } catch(err) {
          // 抛出err
        }
        resolve(true);
      });
    });
  };
});

async function limitRun(taskFns, limit = 10) {
  const results = [];
  const executing = [];

  for (const taskFn of taskFns) {
    const p = Promise.resolve().then(taskFn);
    results.push(p);
    executing.push(p);

    // 任务完成后从执行池移除
    p.finally(() => {
      const idx = executing.indexOf(p);
      if (idx !== -1) executing.splice(idx, 1);
    });

    // 超过并发上限则等待任意一个先完成
    if (executing.length >= limit) {
      await Promise.race(executing);
    }
  }
  return Promise.all(results);
}

await limitRun(taskFns, 10);

当时除了并发请求场景会使用到,也有其他场景下可以使用 Web Locks。比如数据流或媒体流的处理、多任务执行等等场景下。

总结

Promise 和 Web Locks 的结合,可以更轻松高效的解决一些场景下的难题;后续会在业务中持续探索他们的使用场景,与大家分享。

参考文章

MDN-Promise

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CC码码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值