如何在 JavaScript 中取消Promises?

开发 前端
JavaScript 中的 Promises 是管理异步操作的天赐之物,它提供了一种处理成功和失败的简洁方法。

JavaScript 中的 Promises 是管理异步操作的天赐之物,它提供了一种处理成功和失败的简洁方法。

但有一个微妙的挑战:从设计上讲,Promises 拥抱了其异步性质,一旦启动就无法直接停止。

在我们需要更精细控制的情况下,这可能会成为障碍,这时,我们就需要设计可取消的 Promises!

原始 Promise 的问题

想象一下获取大文件或发出网络请求。如果用户决定在中途取消,该怎么办?使用标准 Promise,会陷入困境。它会在后台继续运行,可能会浪费资源。

我们的目标:优雅取消

我们希望为我们的 Promise 提供以下功能:

  • 取消:发起取消请求。
  • 指示状态:了解 Promise 是否已成功取消或已解决。

TaskCancelable 解决方案

以下是我们可以实现 TaskCancelable 函数来增强我们的 Promise 的方法:

export const TaskCancelable = (task) => {
  let _reject;
  let isCancel = false;
  const _status = Symbol("cancel");
  const cancelP = new Promise((resolve, reject) => {
    _reject = reject;
  });
  const p = Promise.race([task, cancelP]);


  p.catch((reason) => {
    if (reason === _status) { 
      isCancel = true;
    }
  });
  p.cancel = () => {
    _reject(_status);
    return p;
  };
  p.isCancel = () => {
    return isCancel;
  };
  return p;
};

解释 

Symbol("cancel"):我们使用 Symbol 来创建取消的唯一标识符。这可以防止与其他潜在错误发生冲突。

Promise.race([task, cancelP]):奇迹就在这里发生!我们将原始任务 Promise 与 cancelP Promise 进行比赛。先解决或先拒绝的一方获胜。

p.cancel():此自定义函数在调用时会拒绝 cancelP Promise,从而有效触发取消。

p.isCancel():这个方便的方法让我们可以检查 Promise 是否确实被取消。

实际示例 

让我们看看如何使用 TaskCancelable:

// Simulate a long-running task
const longTask = new Promise((resolve) => {
  setTimeout(() => {
    resolve("Task complete!");
  }, 3000);
});


const cancellableTask = TaskCancelable(longTask);
// Cancel after 1 second
setTimeout(() => {
  cancellableTask.cancel(); 
}, 1000); 
cancellableTask
  .then((result) => console.log("Success:", result)) // Won't run
  .catch(() => {
    if (cancellableTask.isCancel()) {
      console.log("Task was cancelled!"); 
    } else {
      console.log("Task failed for another reason"); 
    }
  });

结论

通过创建可取消的 Promises,我们在管理异步操作方面获得了更大的灵活性。这种模式对于响应式用户界面和资源密集型任务至关重要,因为取消是这些任务的关键。

责任编辑:华轩 来源: web前端开发
相关推荐

2022-01-21 10:58:39

JavaScriptGolangPython

2021-03-11 23:43:20

JavaScript数组开发

2021-03-18 10:45:02

JavaScript数组运算符

2011-03-21 12:41:41

JavaScript

2014-04-21 10:14:52

PromisesJavaScript

2022-03-15 07:55:09

JavaScript线性仪表图开发

2018-10-11 09:40:53

前端JavaScript编程语言

2024-04-11 08:30:05

JavaScript数组函数

2022-07-07 07:22:01

浏览器JavaScript工具

2020-11-26 08:12:24

JavaScript对象数组

2022-09-12 23:53:53

JavaScript条件判断开发

2015-07-06 09:59:56

JavaScript私有成员

2021-03-29 08:01:20

JavaScript数据结构

2023-06-15 13:01:07

JavaPythonJavaScript

2023-04-26 15:19:36

JavaScripMap数组

2022-06-10 10:24:02

JavaScriptCOVID-19前端

2020-06-17 08:48:22

JavaScript开发技术

2014-12-01 09:54:40

JavaScript

2021-05-08 00:00:27

JavaScript ZIP文件

2020-12-08 08:07:41

JavaScript中等分数组
点赞
收藏

51CTO技术栈公众号