您现在的位置是:亿华云 > 人工智能

Node.js v15.x 新特性 — 控制器对象 AbortController

亿华云2025-10-09 01:19:50【人工智能】6人已围观

简介Node.js v15.0.0 提供了一个全局实用 API AbortController,用于在选定的基于 Promise API 中发出取消信号。无需引入在所有模块中均可使用,该 API 的实现是

Node.js v15.0.0 提供了一个全局实用 API AbortController,新特性控用于在选定的制器基于 Promise API 中发出取消信号。无需引入在所有模块中均可使用,对象该 API 的新特性控实现是基于浏览器中的 Web API AbortController。

简单示例

通俗的制器讲 AbortController 表示一个控制器对象,允许我们根据需要中止一个或多个 Web 请求。对象

下面是新特性控一个示例,在 1 秒后会执行 ac.abort() 方法,制器将会触发 abort 事件,对象并且仅会触发一次,新特性控这可通过 abortSignal.aborted 属性查看前后改变状态。制器

ac.signal.addEventListener(abort,对象 () => {    console.log(Aborted!);   console.log(ac.signal.aborted:, ac.signal.aborted); }, {  once: true }); setTimeout(() => ac.abort(), 1000) console.log(ac.signal.aborted:, ac.signal.aborted); 

中止请求

Node.js 中我们可以选择使用 node-fetch 这个请求处理库,源码下载传递 signal 给 fetch。新特性控

假设这个请求需要等待 5 秒钟,制器大约在 2 秒钟后执行 abort() 将会中止这个请求。对象

const ac = new AbortController(); import fetch from node-fetch; const timer = setTimeout(() => ac.abort(), 2000) try {    const {  statusText } = await fetch(http://localhost:3000/api, {  signal: ac.signal })   console.log(statusText); } catch (err) {    console.log(err.name); // AbortError } finally {    clearTimeout(timer); } 

中止 Promise

传递 ac.signal 中止一个正在运行的 Promise,这需要我们为 ac.signal 注册一个 abort 事件,做一些处理。之后在任何地方调用 ac.abort() 中止 Promise。

使用 Promise 表示中止操作的任何 Web 平台 APIs 都必须遵循以下原则:

通过一个 signal 字典成员接受 AbortSignal 对象。 通过 reject 一个带有 "AbortError" DOMException 这个类的 Promise 来表示操作已中止。 检查 AbortSignal 对象的 aborted 标志是否已经被设置,如果是则立即 reject,亿华云计算否则: 使用中止算法机制来观察对 AbortSignal 对象的更改,并以不会导致与其他观察者冲突的方式进行观察。

以下关于 doSomeThingAsync 这个异步 Promise Function 的实现基本上也是遵循的这些规则。

class AbortError extends Error {    constructor(message) {      super(message);     this.name = AbortError;   } } function doSomethingAsync({  ac }) {    return new Promise((resolve, reject) => {      console.log(task start...);     if (ac.aborted) {        return reject(new AbortError(task handler failed, AbortError));     }     const timer = setTimeout(() => {        console.log(task end...);       resolve(1);     }, 5000);     ac.signal.addEventListener(abort, () => {        clearTimeout(timer);       reject(new AbortError(task handler failed, AbortError));     }, {  once: true });       }); } setTimeout(() => ac.abort(), 2000) try {    await doSomethingAsync({  ac }); } catch (err) {    console.error(err.name, err.message); // AbortError task handler failed } 

注意:在 Node.js 中目前并没有 DOMException 这个类,我们无法这样做 new DOMException(task handler failed, AbortError) 所以我在刚开始先创建了一个 AbortError 类来模拟。

Node.js 中已经有一些异步 API 支持传递 signal,但是它的 DOMException 错误也是在内部通过封装来实现的:

// https://github.com/nodejs/node/blob/f6b1df2226/lib/internal/fs/promises.js#L98 const lazyDOMException = hideStackFrames((message, name) => {    if (DOMException === undefined)     DOMException = internalBinding(messaging).DOMException;   return new DOMException(message, name); }); // 例如 writeFileHandle // https://github.com/nodejs/node/blob/f6b1df2226/lib/internal/fs/promises.js#L282 if (signal?.aborted) {    throw lazyDOMException(The operation was aborted, AbortError); } 

Reference

https://dom.spec.whatwg.org/#abortcontroller-api-integration

https://nodejs.org/docs/latest-v15.x/api/globals.htm

很赞哦!(5655)