什么是 @dmail/cancellation
在编写异步代码时,我们常常需要处理取消操作。例如,用户可能在异步操作还未完成时,关闭了当前页面或停止了原本的操作,这对于异步任务来说就是一个取消操作。
@dmail/cancellation 就是一个处理异步取消操作的 npm 包,它提供了非常便捷的方式,让我们能够集中处理异步操作的取消逻辑,避免了重复编写取消代码的繁琐。
@dmail/cancellation 的使用方法
@dmail/cancellation 的主要对象是 Cancellation 类,通过它的实例,我们能够方便地控制异步操作的取消逻辑。
安装 @dmail/cancellation
首先,我们需要在项目中安装 @dmail/cancellation 包。打开命令行工具,进入项目目录,运行以下命令:
npm i @dmail/cancellation --save
创建 Cancellation 实例
我们需要创建 Cancellation 类的实例,以便控制异步操作的取消逻辑。可以通过以下方式创建一个 Cancellation 实例:
import { Cancellation } from "@dmail/cancellation"; const cancellation = new Cancellation();
在创建实例时,可以传入一个可选的对象参数,来定制取消逻辑的一些行为。例如,可以设置超时时间或最大重试次数等。
import { Cancellation } from "@dmail/cancellation"; const cancellation = new Cancellation({ timeout: 5000, // 超时时间为 5s maxRetry: 3, // 最大重试次数为 3 });
使用 Cancellation 实例来控制异步操作
当异步操作发出后,我们需要将 Cancellation 实例传递给异步操作,以便在需要取消操作时,能够有效地终止异步操作。
例如,在使用 axios 发送 HTTP 请求时,我们可以将 Cancellation 实例作为 axios 的 cancelToken 参数,如下所示:
-- -------------------- ---- ------- ------ ----- ---- -------- ------ - ------------ - ---- ---------------------- ----- ------------ - --- --------------- ----- ------------------------- ----- - ------------ ------------------- -- ---------------- -- - ---------------------- -- -------------- -- - --------------------------- ---
在上述代码中,我们给 axios 的 post 方法传递了一个 cancelToken 参数,该参数的值是 Cancellation 的 token 属性。此时,如果我们需要取消异步操作,只需要调用 Cancellation 的 cancel 方法即可。
cancellation.cancel("请求已取消"); // 取消异步操作,并传递一个取消原因
监听取消事件
Cancellation 实例提供了 cancel 事件,依靠它,我们能够监听异步操作的取消事件,以便进行一些清理操作。
例如,在使用 Apollo Client 发送 GraphQL 请求时,我们可以根据 cancel 事件,取消正在进行的查询,并清理相应的缓存。
以下代码演示了如何监听 Cancellation 的 cancel 事件:
import { Cancellation } from "@dmail/cancellation"; const cancellation = new Cancellation(); cancellation.events.on("cancel", (reason) => { console.log(`异步操作已取消,原因:${reason}`); });
因为 Cancellation 实例是 EventEmitter 的子类,所以我们可以使用 on 方法监听其事件。
示例代码
一个简单的示例
以下代码演示了如何使用 Cancellation 实例控制异步操作的取消逻辑。
-- -------------------- ---- ------- ------ - ------------ - ---- ---------------------- ----- ------------ - --- --------------- ----- ------------------ - ----- -- -- - --- - ----- --- ----------------- ------- -- - ------------------- ------ --- -------------------- - ----- ------- - ----------------------------------------- - -- ---------------------------------------------- -- - ---------------------------------------- --- -- -- ------- ------------- -- - ------------------------------ -- ------
在上述代码中,我们定义了一个异步操作 someAsyncOperation,它执行了一个5s 的定时器,然后输出“操作成功”。在 someAsyncOperation 函数中,我们通过 cancelable 方法创建了一个 CancelablePromise 实例,它将异步操作包装成一个支持取消的 Promise 对象。
在外部代码中,我们先使用 setTimeout 定时器等待5s,然后调用 cancel 方法来取消异步操作。由于我们在 Promise 中使用了 cancel 方法的返回值,所以当异步操作被取消时,会抛出一个 CancelError 异常。我们在 catch 语句中捕获该异常,并输出取消的原因。
使用 Cancellation.token 做 Axios 请求取消
以下代码演示了如何在使用 Axios 发送 HTTP 请求时,使用 Cancellation 实例来控制取消逻辑。
-- -------------------- ---- ------- ------ ----- ---- -------- ------ - ------------ - ---- ---------------------- ----- ------------ - --- --------------- ----- ------------------------- ----- - ------------ ------------------- -- ---------------- -- - ---------------------- -- -------------- -- - -- ---------------- - ------------------------------------------------------- - ---- -- ----------- --- --------------- - ------------------------ - ---- -- ------------------------------------ - ----------------------------------------- - ---- - ---------------------------------------- - --- -- -- ------- ------------- -- - ------------------------------ -- ------
在上述代码中,我们使用 Axios 发送了一个 POST 请求,并传递了一个 cancelToken 参数。该参数的值是 Cancellation 实例的 token 属性。此时,如果我们需要取消异步操作,只需要调用 Cancellation 的 cancel 方法即可。
在 catch 语句中,我们对不同种类的异常进行了捕获与处理。其中,当错误是 Cancellation.isCancellation(error) 返回 true 时,表示该错误是由于异步操作被取消导致的,我们输出取消原因即可。
总结
@dmail/cancellation 很好地封装了异步操作取消的处理逻辑,在我们编写异步代码时,非常值得使用。使用 @dmail/cancellation,我们可以方便地集中管理异步操作取消的逻辑,避免了重复编写取消代码的麻烦,使得我们能够更专注地关注异步操作的核心逻辑。希望本文能够帮助大家更好地学习和使用 @dmail/cancellation 包。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/5f29ed243b0ab45f74a8bab6