{"id":10006425,"date":"2022-09-08T08:13:21","date_gmt":"2022-09-08T00:13:21","guid":{"rendered":"https:\/\/ityet.com\/?p=10006425"},"modified":"2022-09-08T08:13:21","modified_gmt":"2022-09-08T00:13:21","slug":"%e5%a6%82%e4%bd%95%e4%bc%98%e9%9b%85%e5%9c%b0%e4%b8%ad%e6%96%ad-promise%ef%bc%9f%e6%9d%a5%e8%af%95%e8%af%95-abortcontroller-%e5%90%a7%ef%bc%81","status":"publish","type":"post","link":"https:\/\/itmax.cn\/?p=10006425","title":{"rendered":"\u5982\u4f55\u4f18\u96c5\u5730\u4e2d\u65ad Promise\uff1f\u6765\u8bd5\u8bd5 AbortController \u5427\uff01"},"content":{"rendered":"<blockquote><p>\u6b22\u8fce\u5927\u5bb6\u6765\u5230 <a href=\"https:\/\/link.segmentfault.com\/?enc=Dyrob7YSmTT07mE6MT3WPg%3D%3D.E5RrkjVItsjmiZ7yGqTt4%2BAnvs7MWtICOWLLQLylCfys8AFCvhyyX6Kpma0tV%2BpzZEMM%2BL9T2%2FNi0n9O1gj8YTVovSh%2F7nvBWM1KeA%2FKJEw%3D\" rel=\"nofollow\">\u524d\u7aef\u5c0f\u8bfe\u5802<\/a> \u7684\u7b2c\u4e94\u671f\uff0c\u4eca\u5929\u6211\u4eec\u6765\u804a\u4e00\u804a\u5982\u4f55\u7ec8\u6b62\u6b63\u5728\u8fdb\u884c\u4e2d\u7684 <strong>Fetch<\/strong> \u4ee5\u53ca <strong>Promise<\/strong>\u3002\u6587\u4e2d\u4f1a\u8ddf\u5927\u5bb6\u8be6\u7ec6\u4ecb\u7ecd\u8fd9\u91cc\u9762\u7684\u4e24\u4e2a\u5173\u952e\u77e5\u8bc6\u70b9 <strong>AbortController<\/strong> \u548c <strong>AbortSignal<\/strong>\u3002\u5bf9\u52a8\u624b\u5b9e\u8df5\u6bd4\u8f83\u611f\u5174\u8da3\u7684\u540c\u5b66\u8fd8\u53ef\u4ee5\u770b\u5bf9\u5e94\u7684<a href=\"https:\/\/www.bilibili.com\/video\/BV1cU4y167fj\/?vd_source=e46cdfe326b4fdcac050e3c7828c3422\">\u89c6\u9891\u7248\u672c<\/a>\u3002<\/p><\/blockquote>\n<p>\u5927\u5bb6\u5728\u5e73\u65f6\u7684\u5f00\u53d1\u8fc7\u7a0b\u4e2d\u4f30\u8ba1\u4e0d\u4f1a\u7ecf\u5e38\u78b0\u5230\u9700\u8981\u4e3b\u52a8\u53d6\u6d88\u4e00\u4e2a <strong>Fetch<\/strong> \u8bf7\u6c42\u7684\u9700\u6c42\uff0c\u6240\u4ee5\u4e00\u90e8\u5206\u540c\u5b66\u53ef\u80fd\u5bf9\u8fd9\u4e00\u5757\u77e5\u8bc6\u4e0d\u662f\u5f88\u4e86\u89e3\u3002\u6ca1\u6709\u5173\u7cfb\uff0c\u770b\u5b8c\u8fd9\u7bc7\u6587\u7ae0\u4f60\u5c31\u80fd\u591f\u638c\u63e1\u5173\u4e8e\u5982\u4f55\u7ec8\u6b62\u4e00\u4e2a <strong>Fetch<\/strong> \u8bf7\u6c42\u6216\u8005\u4e00\u4e2a <strong>Promise<\/strong> \u7684\u5168\u90e8\u6280\u80fd\u4e86\u3002\u90a3\u6211\u4eec\u8d76\u5feb\u5f00\u59cb\u5427~<\/p>\n<p>\u8fd9\u7bc7\u6587\u7ae0\u6bd4\u6211\u9884\u671f\u8981\u82b1\u8d39\u7684\u65f6\u95f4\u548c\u7cbe\u529b\u8fd8\u8981\u591a\uff0c\u6240\u4ee5\u6587\u7ae0\u6bd4\u8f83\u957f\uff0c\u5927\u5bb6\u73b0\u5728\u6ca1\u65f6\u95f4\u6d4f\u89c8\u7684\u53ef\u4ee5\u5148\u6536\u85cf\u8d77\u6765\uff0c\u4ee5\u540e\u6162\u6162\u770b\u3002\u5982\u679c\u89c9\u5f97\u8fd9\u7bc7\u6587\u7ae0\u4e0d\u9519\u7684\u8bdd\uff0c\u4e5f\u53ef\u4ee5\u5e2e\u5fd9\u70b9\u4e2a\u8d5e\uff0c\u8f6c\u53d1\u652f\u6301\u4e00\u4e0b\u3002<\/p>\n<h3>\u4f7f\u7528 AbortController \u7ec8\u6b62 Fetch \u8bf7\u6c42<\/h3>\n<p>\u5728 <code>fetch<\/code> \u4e4b\u524d\uff0c\u6211\u4eec\u8bf7\u6c42\u540e\u7aef\u7684\u8d44\u6e90\u4f7f\u7528\u7684\u65b9\u5f0f\u662f\u901a\u8fc7 <code>XMLHttpRequest<\/code> \u8fd9\u4e2a\u6784\u9020\u51fd\u6570\uff0c\u521b\u5efa\u4e00\u4e2a <code>xhr<\/code> \u5bf9\u8c61\uff0c\u7136\u540e\u901a\u8fc7\u8fd9\u4e2a <code>xhr<\/code> \u5bf9\u8c61\u8fdb\u884c\u8bf7\u6c42\u7684\u53d1\u9001\u4ee5\u53ca\u63a5\u6536\u3002<\/p>\n<pre><code class=\"javascript\">const xhr = new XMLHttpRequest();\nxhr.addEventListener('load', function (e) {\n  console.log(this.responseText);\n});\nxhr.open('GET', 'https:\/\/jsonplaceholder.typicode.com\/todos\/1');\nxhr.send();\n<\/code><\/pre>\n<p>\u8fd9\u4e2a <code>xhr<\/code> \u4e0a\u4e5f\u5b58\u5728\u4e00\u4e2a <code>abort<\/code> \u65b9\u6cd5\u7528\u6765\u8fdb\u884c\u8bf7\u6c42\u7684\u7ec8\u6b62\u64cd\u4f5c\u3002\u4f46\u662f\u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u8fd9\u4e2a <code>abort<\/code> \u7684\u6267\u884c\u8fc7\u7a0b\u662f\u6bd4\u8f83\u6a21\u7cca\u7684\u3002 \u6211\u4eec\u4e0d\u6e05\u695a <code>abort<\/code> \u5728\u4ec0\u4e48\u65f6\u5019\u53ef\u4ee5\u4e0d\u8fdb\u884c\u6216\u7ec8\u6b62\u5bf9\u5e94\u7684\u7f51\u7edc\u8bf7\u6c42\uff0c\u53c8\u6216\u8005\u5982\u679c\u5728\u8c03\u7528 <code>abort<\/code> \u65b9\u6cd5\u548c\u83b7\u53d6\u5230\u8bf7\u6c42\u7684\u8d44\u6e90\u4e4b\u95f4\u5b58\u5728\u7ade\u4e89\u6761\u4ef6\u7684\u65f6\u5019\u4f1a\u53d1\u751f\u4ec0\u4e48\u3002\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u7b80\u5355\u7684\u4ee3\u7801\u6765\u5b9e\u8df5\u4e00\u4e0b\uff1a<\/p>\n<pre><code class=\"javascript\">\/\/ ... \u7701\u7565\u6389\u4e0a\u9762\u7684\u4ee3\u7801\nsetTimeout(() =&gt; {\n  xhr.abort();\n}, 10);<\/code><\/pre>\n<p>\u901a\u8fc7\u6dfb\u52a0\u4e00\u4e2a\u5ef6\u65f6\uff0c\u7136\u540e\u53d6\u6d88\u6389\u5bf9\u5e94\u7684\u8bf7\u6c42\uff1b\u5728\u63a7\u5236\u53f0\u53ef\u4ee5\u770b\u5230\uff0c\u6709\u65f6\u8bf7\u6c42\u5df2\u7ecf\u83b7\u53d6\u5230\u7ed3\u679c\u4e86\uff0c\u4f46\u662f\u5374\u6ca1\u6709\u6253\u5370\u51fa\u5bf9\u5e94\u7684\u7ed3\u679c\uff1b\u6709\u65f6\u8bf7\u6c42\u6ca1\u6709\u83b7\u53d6\u5230\u5bf9\u5e94\u7684\u7ed3\u679c\uff0c\u4f46\u662f\u67e5\u770b\u5bf9\u5e94\u7684\u7f51\u7edc\u7684\u72b6\u6001\u5374\u662f\u6210\u529f\u7684\u3002\u6240\u4ee5\u8fd9\u91cc\u9762\u6709\u5f88\u591a\u7684\u4e0d\u786e\u5b9a\u6027\uff0c\u8ddf\u6211\u4eec\u7684\u611f\u89c9\u662f\u6bd4\u8f83\u6a21\u7cca\u7684\u3002<br \/>\u7b49\u5230 <code>fetch<\/code> \u51fa\u6765\u7684\u65f6\u5019\uff0c\u5927\u5bb6\u5c31\u5728\u8ba8\u8bba\u5173\u4e8e\u5982\u4f55\u6b63\u786e\uff0c\u6e05\u695a\u5730\u53d6\u6d88\u4e00\u4e2a <code>fetch<\/code> \u8bf7\u6c42\u3002\u6700\u65e9\u7684\u8ba8\u8bba\u53ef\u4ee5\u770b\u8fd9\u91cc <a href=\"https:\/\/link.segmentfault.com\/?enc=2yKN7fbQcowZJtIpXt%2BiFg%3D%3D.qF%2BOIokhhDNjMKAd%2BDZ2qPfUnDQZX74ZHV4EkQrZZQ8ikpBi4IuWE4kjG1xQ1%2BBo\" rel=\"nofollow\">Aborting a fetch #27<\/a> \uff0c\u90a3\u5df2\u7ecf\u662f7\u5e74\u524d\uff082015\u5e74\uff09\u7684\u4e8b\u60c5\u4e86\uff0c\u53ef\u4ee5\u770b\u5230\u5f53\u65f6\u7684\u8ba8\u8bba\u8fd8\u662f\u6bd4\u8f83\u6fc0\u70c8\u7684\u3002\u5927\u5bb6\u611f\u5174\u8da3\u7684\u8bdd\u53ef\u4ee5\u770b\u770b\u5f53\u65f6\u5927\u5bb6\u90fd\u4e3b\u8981\u5173\u6ce8\u7684\u662f\u54ea\u4e9b\u7279\u6027\u3002<\/p>\n<p>\u6700\u7ec8\uff0c<a href=\"https:\/\/link.segmentfault.com\/?enc=NSTgJv%2BGTtPBdOWYSdbk%2BA%3D%3D.wjAim7NkumVUIsA6CaA9DciWGC2ECvjguOPqRvvEZ7x5TxhCCTNVLh4IH26xeSzljy528CYPFjBQHDsoWGB4lA%3D%3D\" rel=\"nofollow\">\u65b0\u7684\u89c4\u8303<\/a> \u51fa\u6765\u4e86\uff0c\u901a\u8fc7 <code>AbortController<\/code> \u548c <code>AbortSignal<\/code> \u6211\u4eec\u53ef\u4ee5\u65b9\u4fbf\uff0c\u5feb\u6377\uff0c\u6e05\u695a\u5730\u7ec8\u6b62\u4e00\u4e2a <code>fetch<\/code> \u8bf7\u6c42\u3002\u8981\u6ce8\u610f\u7684\u662f\uff0c\u8fd9\u4e2a\u89c4\u8303\u662f\u4e00\u4e2a <strong>DOM<\/strong> \u5c42\u9762\u7684\u89c4\u8303\uff0c\u4e0d\u662f <strong>JavaScript<\/strong> \u8bed\u8a00\u5c42\u9762\u7684\u89c4\u8303\u3002\u73b0\u5728\u7edd\u5927\u591a\u6570\u7684\u6d4f\u89c8\u5668\u73af\u5883\u548c\u65b0\u7248\u672c\u7684 <strong>Node.js<\/strong> \u73af\u5883\u4e5f\u90fd\u652f\u6301\u8fd9\u4e2a\u7279\u6027\u4e86\u3002\u5173\u4e8e <code>AbortController<\/code> \u7684\u517c\u5bb9\u6027\uff0c\u5927\u5bb6\u53ef\u4ee5\u53c2\u8003\u8fd9\u91cc <a href=\"https:\/\/link.segmentfault.com\/?enc=tq6k1bw3evDi6rZBJGdIqw%3D%3D.ViG7BvPneYH%2B3RmhhKejw5FCB4%2F%2F62Ev0KUvtQk%2F4UJ0h3FjxM5g%2Fb%2B27p3kj06jeZWaOzm%2FufQwV5SWTD3Py18HoqO47MBlRZWTLlUycSHExJdlhyJohh3ETa1TdUt9\" rel=\"nofollow\">AbortController#browser_compatibility<\/a><\/p>\n<p>\u4e0b\u9762\u6587\u7ae0\u4e2d\u7684\u4ee3\u7801\u4f8b\u5b50\u57fa\u672c\u4e0a\u90fd\u53ef\u4ee5\u76f4\u63a5\u590d\u5236\u7c98\u8d34\u5230\u63a7\u5236\u53f0\u8fd0\u884c\u7684\uff0c\u6240\u4ee5\u611f\u5174\u8da3\u7684\u540c\u5b66\u9605\u8bfb\u5230\u5bf9\u5e94\u7684\u90e8\u5206\u53ef\u4ee5\u76f4\u63a5\u6253\u5f00\u6d4f\u89c8\u5668\u7684\u63a7\u5236\u53f0\u53bb\u8fd0\u884c\u4e00\u4e0b\uff0c\u7136\u540e\u770b\u770b\u5bf9\u5e94\u7684\u7ed3\u679c\u3002\u52a0\u6df1\u4e00\u4e0b\u81ea\u5df1\u5bf9\u76f8\u5173\u77e5\u8bc6\u70b9\u7684\u8bb0\u5fc6\u3002<\/p>\n<h4>\u7ec8\u6b62\u6b63\u5728\u8fdb\u884c\u4e2d\u7684\u5355\u4e2a\u8bf7\u6c42<\/h4>\n<p>\u6211\u4eec\u5148\u901a\u8fc7\u4e00\u6bb5\u4ee3\u7801\u6765\u7ed9\u5927\u5bb6\u5c55\u793a\u4e00\u4e0b\u5982\u4f55\u5b9e\u73b0\u8fd9\u4e2a\u529f\u80fd<\/p>\n<pre><code class=\"javascript\">const ac = new AbortController();\nconst { signal } = ac;\n\nconst resourceUrl = 'https:\/\/jsonplaceholder.typicode.com\/todos\/1';\nfetch(resourceUrl, { signal })\n  .then(response =&gt; response.json())\n  .then(json =&gt; console.log(json))\n  .catch(err =&gt; {\n    \/\/ \u4e0d\u540c\u6d4f\u89c8\u5668\u7684\u8fd4\u56de\u7ed3\u679c\u4e0d\u540c\n    console.log(err);\n  });\n\n\/\/ \u53ef\u4ee5\u7acb\u5373\u7ec8\u6b62\u8bf7\u6c42\uff0c\u6216\u8005\u8bbe\u7f6e\u4e00\u4e2a\u5b9a\u65f6\u5668\n\/\/ ac.abort();\nsetTimeout(() =&gt; {\n  ac.abort();\n}, 10);\n<\/code><\/pre>\n<p>\u5927\u5bb6\u611f\u5174\u8da3\u7684\u8bdd\u4e5f\u53ef\u4ee5\u628a\u4e0a\u9762\u7684\u4ee3\u7801\u590d\u5236\u7c98\u8d34\u5230\u6d4f\u89c8\u5668\u7684\u63a7\u5236\u53f0\u8fd0\u884c\u4e00\u4e0b\uff0c\u4e0a\u9762\u4ee3\u7801\u7684\u8fd0\u884c\u7ed3\u679c\u5982\u4e0b\u6240\u793a\uff1a<\/p>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/bVc2gDR\" alt=\"0\" title=\"0\" loading=\"lazy\"><br \/><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/bVc2gDV\" alt=\"1\" title=\"1\" loading=\"lazy\"><\/p>\n<p>\u53ef\u4ee5\u770b\u5230\u63a7\u5236\u53f0\u7684 <strong>Console<\/strong> \u7684\u8f93\u51fa\u662f\uff1a<strong>DOMException: The user aborted a request.<\/strong><br \/>\u5bf9\u5e94\u7684 <strong>Network<\/strong> \u5c55\u793a\u7684\u662f\u4e00\u4e2a\u53d6\u6d88\u72b6\u6001\u7684\u8bf7\u6c42\u3002\u8fd9\u8bf4\u660e\u6211\u4eec\u521a\u624d\u53d1\u9001\u7684\u8bf7\u6c42\u88ab\u7ec8\u6b62\u53d6\u6d88\u6389\u4e86\u3002<br \/><strong>\u80fd\u591f\u5728\u4e00\u4e9b\u7279\u5b9a\u7684\u60c5\u51b5\u4e0b\u4e3b\u52a8\u5730\u53d6\u6d88\u76f8\u5173\u7684\u8bf7\u6c42\u5bf9\u6211\u4eec\u5e94\u7528\u6765\u8bf4\u662f\u5f88\u91cd\u8981\u7684\uff0c\u8fd9\u80fd\u591f\u51cf\u5c11\u6211\u4eec\u7528\u6237\u7684\u6d41\u91cf\u4f7f\u7528\u4ee5\u53ca\u6211\u4eec\u5e94\u7528\u7684\u5185\u5b58\u4f7f\u7528\u3002<\/strong><\/p>\n<h4>AbortController \u7684\u6df1\u5165\u5256\u6790<\/h4>\n<p>\u63a5\u4e0b\u6765\u6211\u4eec\u6765\u8bb2\u89e3\u4e00\u4e0b\u4e0a\u9762\u7684\u4ee3\u7801\uff0c\u7b2c\u4e00\u884c\u901a\u8fc7 <code>AbortController<\/code> \u521b\u5efa\u4e86\u4e00\u4e2a <code>AbortController<\/code> \u7c7b\u578b\u7684\u5b9e\u4f8b <code>ac<\/code>\uff0c\u8fd9\u4e2a\u5b9e\u4f8b\u4e0a\u6709\u4e00\u4e2a <code>abort<\/code> \u65b9\u6cd5\u548c\u4e00\u4e2a <code>AbortSignal<\/code> \u7c7b\u578b\u7684 <code>signal<\/code> \u5b9e\u4f8b\u3002\u7136\u540e\u6211\u4eec\u901a\u8fc7 <code>fetch<\/code> \u65b9\u6cd5\u53bb\u8bf7\u6c42\u4e00\u4e2a\u8d44\u6e90\u8def\u5f84\uff0c\u4f20\u9012\u7ed9 <code>fetch<\/code> \u7684\u9009\u9879\u628a <code>ac<\/code> \u7684 <code>signal<\/code> \u5bf9\u8c61\u4f20\u9012\u8fdb\u53bb\u3002<code>fetch<\/code> \u65b9\u6cd5\u5982\u679c\u83b7\u53d6\u5230\u4e86\u8d44\u6e90\u5c31\u4f1a\u628a\u8d44\u6e90\u6253\u5370\u5230\u63a7\u5236\u53f0\uff0c\u5982\u679c\u7f51\u7edc\u53d1\u751f\u4e86\u95ee\u9898\uff0c\u5c31\u4f1a\u6355\u83b7\u5f02\u5e38\uff0c\u7136\u540e\u628a\u5f02\u5e38\u6253\u5370\u5230\u63a7\u5236\u53f0\u3002\u6700\u540e\uff0c\u901a\u8fc7\u4e00\u4e2a <code>setTimeout<\/code> \u5ef6\u65f6\uff0c\u8c03\u7528 <code>ac<\/code> \u7684 <code>abort<\/code> \u65b9\u6cd5\u7ec8\u6b62 <code>fetch<\/code> \u8bf7\u6c42 \u3002<\/p>\n<p><code>fetch<\/code> \u7684 <code>options<\/code> \u9009\u9879\u5141\u8bb8\u6211\u4eec\u4f20\u9012\u4e00\u4e2a <code>signal<\/code> \u5bf9\u8c61\uff1b<strong><code>fetch<\/code> \u7684\u5185\u90e8\u4f1a\u76d1\u6d4b\u8fd9\u4e2a\u5bf9\u8c61\u7684\u72b6\u6001\uff0c\u5982\u679c\u8fd9\u4e2a\u5bf9\u8c61\u7684\u72b6\u6001\u4ece\u672a\u7ec8\u6b62\u7684\u72b6\u6001\u53d8\u4e3a\u7ec8\u6b62\u7684\u72b6\u6001\u7684\u8bdd\uff0c\u5e76\u4e14 <code>fetch<\/code> \u8bf7\u6c42\u8fd8\u5728\u8fdb\u884c\u4e2d\u7684\u8bdd\uff0c<code>fetch<\/code> \u8bf7\u6c42\u5c31\u4f1a\u7acb\u5373\u5931\u8d25\u3002\u5176\u5bf9\u5e94\u7684 <code>Promise<\/code> \u7684\u72b6\u6001\u5c31\u4f1a\u53d8\u4e3a <code>Rejected<\/code><\/strong>\u3002<\/p>\n<p>\u5982\u4f55\u6539\u53d8 <code>signal<\/code> \u7684\u72b6\u6001\u5462\uff1f\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u8c03\u7528 <code>ac<\/code> \u7684 <code>abort<\/code> \u65b9\u6cd5\u53bb\u6539\u53d8 <code>signal<\/code> \u7684\u72b6\u6001\u3002\u4e00\u65e6\u6211\u4eec\u8c03\u7528\u4e86 <code>ac.abort()<\/code> \u90a3\u4e48\u4e0e\u4e4b\u5173\u8054\u7684 <code>signal<\/code> \u7684\u72b6\u6001\u4f1a\u7acb\u523b\u4ece\u8d77\u59cb\u72b6\u6001\uff08\u975e\u7ec8\u6b62\u72b6\u6001\uff09\u8f6c\u53d8\u4e3a\u7ec8\u6b62\u72b6\u6001\u3002<\/p>\n<p>\u6211\u4eec\u4e0a\u9762\u53ea\u662f\u7b80\u5355\u5730\u4f7f\u7528\u4e86 <code>signal<\/code> \u5bf9\u8c61\uff0c\u8fd9\u4e2a\u5bf9\u8c61\u662f <code>AbortSignal<\/code> \u7c7b\u7684\u5b9e\u4f8b\uff0c\u5bf9\u4e8e <code>AbortSignal<\/code> \u6211\u4eec\u4e0b\u9762\u4f1a\u505a\u6df1\u5165\u7684\u8bb2\u89e3\uff0c\u8fd9\u91cc\u6682\u65f6\u53ea\u9700\u8981\u77e5\u9053 <code>signal<\/code> \u53ef\u4ee5\u4f5c\u4e3a\u4e00\u4e2a\u4fe1\u53f7\u5bf9\u8c61\u4f20\u9012\u7ed9 <code>fetch<\/code> \u65b9\u6cd5\uff0c\u53ef\u4ee5\u7528\u6765\u7ec8\u6b62 <code>fetch<\/code> \u7684\u7ee7\u7eed\u8fdb\u884c\u3002<br \/>\u53e6\u5916\uff0c\u5728\u4e0d\u540c\u7684\u6d4f\u89c8\u5668\u4e2d\u6253\u5370\u7684\u7ed3\u679c\u53ef\u80fd\u7565\u6709\u4e0d\u540c\uff0c\u8fd9\u4e2a\u8ddf\u4e0d\u540c\u6d4f\u89c8\u5668\u7684\u5185\u90e8\u5b9e\u73b0\u6709\u5173\u7cfb\u3002\u6bd4\u5982\u5728 <strong>Firefox<\/strong> \u4e2d\u7684\u7ed3\u679c\u5982\u4e0b\uff1a<\/p>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/bVc2gDW\" alt=\"2\" title=\"2\" loading=\"lazy\"><br \/><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/bVc2gDX\" alt=\"3\" title=\"3\" loading=\"lazy\"><\/p>\n<p>\u5728 <strong>Safari<\/strong> \u4e2d\u7684\u7ed3\u679c\u5982\u4e0b\uff1a<\/p>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/bVc2gDY\" alt=\"4\" title=\"4\" loading=\"lazy\"><br \/><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/bVc2gDZ\" alt=\"5\" title=\"5\" loading=\"lazy\"><\/p>\n<p>\u5f53\u7136\u5982\u679c\u6211\u4eec\u6ca1\u6709\u7ec8\u6b62 <code>fetch<\/code> \u8bf7\u6c42\u7684\u8bdd\uff0c\u63a7\u5236\u53f0\u7684\u6253\u5370\u5c06\u4f1a\u662f\uff1a<\/p>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/bVc2gD1\" alt=\"6\" title=\"6\" loading=\"lazy\"><\/p>\n<p>\u53e6\u5916\u5927\u5bb6\u5982\u679c\u9700\u8981\u4e00\u4e9b\u6a21\u62df\u7684\u6570\u636e\u63a5\u53e3\u7684\u8bdd\u53ef\u4ee5\u8bd5\u8bd5 <a href=\"https:\/\/link.segmentfault.com\/?enc=Lp3WP5oq7AfoIkrV4b0ZeQ%3D%3D.s2Hx9vQ8YFGhbTGpqDbHODLfpcFBzkqujNFZrbKa4ignBoRa5FGdYmaAeQ3uvTex\" rel=\"nofollow\">JSONPlaceholder<\/a> \uff0c\u8fd8\u662f\u5f88\u65b9\u4fbf\u4f7f\u7528\u7684\u3002<\/p>\n<h4>\u6279\u91cf\u53d6\u6d88\u591a\u4e2a fetch \u8bf7\u6c42<\/h4>\n<p>\u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0c\u6211\u4eec\u7684 <code>signal<\/code> \u5bf9\u8c61\u53ef\u4ee5\u540c\u65f6\u4f20\u9012\u7ed9\u591a\u4e2a\u8bf7\u6c42\uff0c\u5728\u9700\u8981\u7684\u60c5\u51b5\u4e0b\u53ef\u4ee5\u540c\u65f6\u53d6\u6d88\u591a\u4e2a\u8bf7\u6c42\uff1b\u6211\u4eec\u6765\u770b\u770b\u5982\u4f55\u8fdb\u884c\u8fd9\u6837\u7684\u64cd\u4f5c\u3002\u4ee3\u7801\u5982\u4e0b\u6240\u793a\uff1a<\/p>\n<pre><code class=\"javascript\">const ac = new AbortController();\nconst { signal } = ac;\n\nconst resourcePrefix = 'https:\/\/jsonplaceholder.typicode.com\/todos\/';\nfunction todoRequest (id, { signal } = {}) {\n  return fetch(`${resourcePrefix}${id}`, { signal })\n    .then(response =&gt; response.json())\n    .then(json =&gt; console.log(json))\n    .catch(e =&gt; console.log(e));\n}\n\ntodoRequest(1, { signal });\ntodoRequest(2, { signal });\ntodoRequest(3, { signal });\n\n\/\/ \u540c\u65f6\u7ec8\u6b62\u591a\u4e2a\u8bf7\u6c42\nac.abort();\n<\/code><\/pre>\n<p>\u8fd0\u884c\u4ee3\u7801\u540e\u53ef\u4ee5\u5728\u63a7\u5236\u53f0\u770b\u5230\u5982\u4e0b\u7ed3\u679c\uff1a<\/p>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/bVc2gD2\" alt=\"7\" title=\"7\" loading=\"lazy\"><br \/><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/bVc2gD3\" alt=\"8\" title=\"8\" loading=\"lazy\"><\/p>\n<p>\u5982\u679c\u6211\u4eec\u9700\u8981\u540c\u65f6\u5bf9\u591a\u4e2a\u8bf7\u6c42\u8fdb\u884c\u7ec8\u6b62\u64cd\u4f5c\u7684\u7684\u8bdd\uff0c\u4f7f\u7528\u4e0a\u9762\u8fd9\u79cd\u65b9\u5f0f\u975e\u5e38\u7b80\u5355\u65b9\u4fbf\u3002<\/p>\n<p>\u5982\u679c\u6211\u4eec\u60f3\u81ea\u5b9a\u4e49\u7ec8\u6b62\u8bf7\u6c42\u7684\u539f\u56e0\u7684\u8bdd\uff0c\u53ef\u4ee5\u76f4\u63a5\u5728 <code>abort<\/code> \u65b9\u6cd5\u91cc\u4f20\u9012\u6211\u4eec\u60f3\u8981\u7684\u539f\u56e0\uff0c\u8fd9\u4e2a\u53c2\u6570\u53ef\u4ee5\u662f\u4efb\u4f55 <code>JavaScript<\/code> \u7c7b\u578b\u7684\u503c\u3002\u4f20\u9012\u7684\u7ec8\u6b62\u7684\u539f\u56e0\u4f1a\u88ab <code>signal<\/code> \u63a5\u6536\u5230\uff0c\u7136\u540e\u653e\u5728\u5b83\u7684 <code>reason<\/code> \u5c5e\u6027\u4e2d\u3002\u8fd9\u4e2a\u6211\u4eec\u4e0b\u9762\u4f1a\u8bb2\u5230\u3002<\/p>\n<p><code>AbortController<\/code> \u7684\u76f8\u5173\u5c5e\u6027\u548c\u65b9\u6cd5<\/p>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/bVc2gD4\" alt=\"9\" title=\"9\" loading=\"lazy\"><\/p>\n<h3>\u8be6\u7ec6\u4ecb\u7ecd AbortSignal<\/h3>\n<h4>AbortSignal \u7684\u5c5e\u6027\u548c\u65b9\u6cd5<\/h4>\n<p><code>AbortSignal<\/code> \u63a5\u53e3\u7ee7\u627f\u81ea <a href=\"https:\/\/link.segmentfault.com\/?enc=CoqMrt5HfO6HSBbo58GIgw%3D%3D.wkx5yzOODJruGm5YOPWQDHLHWhhsBieNsZywB8r5a4PvzInyXCe4BTGMVw%2BKBPSUFyBmYMapvF3I7DcRP9NPPg%3D%3D\" rel=\"nofollow\">EventTarget<\/a> \uff0c\u6240\u4ee5 <code>EventTarget<\/code> \u5bf9\u5e94\u7684\u5c5e\u6027\u548c\u65b9\u6cd5\uff0c<code>AbortSignal<\/code> \u90fd\u7ee7\u627f\u4e0b\u6765\u4e86\u3002\u5f53\u7136\u8fd8\u6709\u4e00\u4e9b\u81ea\u5df1\u7279\u6709\u7684\u65b9\u6cd5\u548c\u5c5e\u6027\uff0c\u6211\u4eec\u4e0b\u9762\u4f1a\u4e00\u4e00\u8bb2\u89e3\u5230\u7684\u3002\u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c<code>AbortSignal<\/code> \u90e8\u5206\u5c5e\u6027\u6709\u517c\u5bb9\u6027\u95ee\u9898\uff0c\u5177\u4f53\u7684\u517c\u5bb9\u6027\u5927\u5bb6\u53ef\u4ee5\u53c2\u8003\u8fd9\u91cc <a href=\"https:\/\/link.segmentfault.com\/?enc=InVqyCEKuHJmIY6zgixzCQ%3D%3D.S5hA4UYS1Po5ihzt12bg0GJDCeoGCgMP%2FRVCVZy%2FfeooieFKxgqj12i0PiWTlg%2BbzH%2FhOUAL8%2BwKlc9Eoxc39QoEUHgN1GV9YAiHcQ7OpnS%2FTCsU%2BbsVrmnI5vLZlL5n\" rel=\"nofollow\">AbortSignal#browser_compatibility<\/a> \u3002<\/p>\n<h5>\u9759\u6001\u65b9\u6cd5 abort \u548c timeout<\/h5>\n<p>\u8fd9\u4e24\u4e2a\u65b9\u6cd5\u662f <code>AbortSignal<\/code> \u7c7b\u4e0a\u7684\u9759\u6001\u65b9\u6cd5\uff0c\u7528\u6765\u521b\u9020 <code>AbortSignal<\/code> \u5b9e\u4f8b\u3002\u5176\u4e2d <code>abort<\/code> \u7528\u6765\u521b\u9020\u4e00\u4e2a\u5df2\u7ecf\u88ab\u7ec8\u6b62\u7684\u4fe1\u53f7\u5bf9\u8c61\u3002\u6211\u4eec\u6765\u770b\u4e0b\u9762\u7684\u4f8b\u5b50\uff1a<\/p>\n<pre><code class=\"javascript\">\/\/ ... \u7701\u7565 todoRequest \u51fd\u6570\u7684\u5b9a\u4e49\n\/\/ Safari \u6682\u65f6\u4e0d\u652f\u6301\uff0c Firefox \u548c Chrome \u652f\u6301\n\/\/ abort \u53ef\u4ee5\u4f20\u9012\u7ec8\u6b62\u7684\u539f\u56e0\nconst abortedAS = AbortSignal.abort();\n\/\/ \u518d\u53d1\u9001\u4e4b\u524d\u4fe1\u53f7\u7ec8\u6b62\uff0c\u8bf7\u6c42\u4e0d\u4f1a\u88ab\u53d1\u9001\ntodoRequest(1, { signal: abortedAS });\nconsole.warn(abortedAS);\n<\/code><\/pre>\n<p>\u8fd0\u884c\u4ee3\u7801\uff0c\u63a7\u5236\u53f0\u7684\u8f93\u51fa\u7ed3\u679c\u5982\u4e0b\uff1a<\/p>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/bVc2gD5\" alt=\"10\" title=\"10\" loading=\"lazy\"><\/p>\n<p>\u5bf9\u5e94\u7684\u8bf7\u6c42\u751a\u81f3\u90fd\u6ca1\u6709\u53d1\u9001\u51fa\u53bb<\/p>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/bVc2gD9\" alt=\"11\" title=\"11\" loading=\"lazy\"><\/p>\n<p>\u6211\u4eec\u4e5f\u53ef\u4ee5\u7ed9 <code>abort<\/code> \u65b9\u6cd5\u4f20\u9012\u7ec8\u6b62\u7684\u539f\u56e0\uff0c\u6bd4\u5982\u662f\u4e00\u4e2a\u5bf9\u8c61\uff1a<\/p>\n<pre><code class=\"javascript\">\/\/ ...\nconst abortedAS = AbortSignal.abort({\n  type: 'USER_ABORT_ACTION',\n  msg: '\u7528\u6237\u7ec8\u6b62\u4e86\u64cd\u4f5c'\n});\n\/\/ ...<\/code><\/pre>\n<p>\u90a3\u4e48\u8f93\u51fa\u7684\u7ed3\u679c\u5c31\u5982\u4e0b\u56fe\u6240\u793a\uff1a<\/p>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/bVc2gEa\" alt=\"12\" title=\"12\" loading=\"lazy\"><\/p>\n<p><code>signal<\/code> \u7684 <code>reason<\/code> \u5c5e\u6027\u5c31\u53d8\u6210\u4e86\u6211\u4eec\u81ea\u5b9a\u4e49\u7684\u503c\u3002<\/p>\n<p>\u540c\u6837\u7684\uff0c\u5927\u5bb6\u770b\u5230 <code>timeout<\/code> \u5e94\u8be5\u5f88\u5bb9\u6613\u60f3\u5230\u662f\u521b\u9020\u4e00\u4e2a\u591a\u5c11<strong>\u6beb\u79d2<\/strong>\u540e\u4f1a\u88ab\u7ec8\u6b62\u7684 <code>signal<\/code> \u5bf9\u8c61\u3002\u4ee3\u7801\u5982\u4e0b\uff1a<\/p>\n<pre><code class=\"javascript\">\/\/ ... \u7701\u7565\u90e8\u5206\u4ee3\u7801\nconst timeoutAS = AbortSignal.timeout(10);\ntodoRequest(1, { signal: timeoutAS }).then(() =&gt; {\n  console.warn(timeoutAS);\n});\nconsole.log(timeoutAS);\n<\/code><\/pre>\n<p>\u4ee3\u7801\u7684\u8fd0\u884c\u7ed3\u679c\u5982\u4e0b\uff1a<\/p>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/bVc2gEb\" alt=\"13\" title=\"13\" loading=\"lazy\"><\/p>\n<p>\u53ef\u4ee5\u770b\u5230\u6211\u4eec\u6253\u5370\u4e86\u4e24\u6b21 <code>timeoutAS<\/code>\uff0c\u7b2c\u4e00\u6b21\u662f\u7acb\u5373\u6253\u5370\u7684\uff0c\u7b2c\u4e8c\u6b21\u662f\u7b49\u5230\u8bf7\u6c42\u88ab\u7ec8\u6b62\u540e\u6253\u5370\u7684\u3002\u53ef\u4ee5\u770b\u5230\u7b2c\u4e00\u6253\u5370\u7684\u65f6\u5019\uff0c<code>timeoutAS<\/code> \u7684\u72b6\u6001\u8fd8\u662f\u6ca1\u6709\u88ab\u7ec8\u6b62\u7684\u72b6\u6001\u3002\u5f53\u8bf7\u6c42\u88ab\u7ec8\u6b62\u540e\uff0c\u7b2c\u4e8c\u6b21\u6253\u5370\u7684\u7ed3\u679c\u8868\u660e <code>timeoutAS<\/code> \u8fd9\u4e2a\u65f6\u5019\u5df2\u7ecf\u88ab\u7ec8\u6b62\u4e86\uff0c\u5e76\u4e14 <code>reason<\/code> \u5c5e\u6027\u7684\u503c\u8868\u660e\u4e86\u8fd9\u6b21\u8bf7\u6c42\u88ab\u7ec8\u6b62\u662f\u56e0\u4e3a\u8d85\u65f6\u7684\u539f\u56e0\u3002<\/p>\n<h5>\u5c5e\u6027 aborted \u548c reason<\/h5>\n<p><code>AbortSignal<\/code> \u5b9e\u4f8b\u6709\u4e24\u4e2a\u5c5e\u6027\uff1b\u4e00\u4e2a\u662f <code>aborted<\/code> \u8868\u793a\u5f53\u524d\u4fe1\u53f7\u5bf9\u8c61\u7684\u72b6\u6001\u662f\u5426\u662f\u7ec8\u6b62\u7684\u72b6\u6001\uff0c<code>false<\/code> \u662f\u8d77\u59cb\u72b6\u6001\uff0c\u8868\u793a\u4fe1\u53f7\u6ca1\u6709\u88ab\u7ec8\u6b62\uff0c<code>true<\/code> \u8868\u793a\u4fe1\u53f7\u5bf9\u8c61\u5df2\u7ecf\u88ab\u7ec8\u6b62\u4e86\u3002<\/p>\n<p><code>reason<\/code> \u5c5e\u6027\u53ef\u4ee5\u662f\u4efb\u4f55\u7684 <code>JavaScript<\/code> \u7c7b\u578b\u7684\u503c\uff0c\u5982\u679c\u6211\u4eec\u5728\u8c03\u7528 <code>abort<\/code> \u65b9\u6cd5\u7684\u65f6\u5019\u6ca1\u6709\u4f20\u9012\u7ec8\u6b62\u4fe1\u53f7\u7684\u539f\u56e0\uff0c\u90a3\u4e48\u5c31\u4f1a\u4f7f\u7528\u9ed8\u8ba4\u7684\u539f\u56e0\u3002\u9ed8\u8ba4\u7684\u539f\u56e0\u6709\u4e24\u79cd\uff0c\u4e00\u79cd\u662f\u901a\u8fc7 <code>abort<\/code> \u65b9\u6cd5\u7ec8\u6b62\u4fe1\u53f7\u5bf9\u8c61\uff0c\u5e76\u4e14\u6ca1\u6709\u4f20\u9012\u7ec8\u6b62\u7684\u539f\u56e0\uff0c\u90a3\u4e48\u8fd9\u4e2a\u65f6\u5019 <code>reason<\/code> \u7684\u9ed8\u8ba4\u503c\u5c31\u662f\uff1a <code>DOMException: signal is aborted without reason<\/code>\uff1b\u5982\u679c\u662f\u901a\u8fc7 <code>timeout<\/code> \u65b9\u6cd5\u7ec8\u6b62\u4fe1\u53f7\u5bf9\u8c61\uff0c\u90a3\u4e48\u8fd9\u4e2a\u65f6\u5019\u7684\u9ed8\u8ba4\u539f\u56e0\u5c31\u662f\uff1a<code>DOMException: signal timed out<\/code>\u3002\u5982\u679c\u6211\u4eec\u4e3b\u52a8\u4f20\u9012\u4e86\u7ec8\u6b62\u7684\u539f\u56e0\uff0c\u90a3\u4e48\u5bf9\u5e94\u7684 <code>reason<\/code> \u7684\u503c\u5c31\u662f\u6211\u4eec\u4f20\u9012\u8fdb\u53bb\u7684\u503c\u3002<\/p>\n<h5>\u5b9e\u4f8b\u65b9\u6cd5 throwIfAborted<\/h5>\n<p>\u8fd9\u4e2a\u65b9\u6cd5\u901a\u8fc7\u540d\u79f0\u5927\u5bb6\u4e5f\u80fd\u731c\u51fa\u6765\u662f\u4ec0\u4e48\u4f5c\u7528\uff0c\u90a3\u5c31\u662f\u5f53\u8c03\u7528 <code>throwIfAborted<\/code> \u7684\u65f6\u5019\uff0c\u5982\u679c\u8fd9\u4e2a\u65f6\u5019 <code>signal<\/code> \u5bf9\u8c61\u7684\u72b6\u6001\u662f\u7ec8\u6b62\u7684\uff0c\u90a3\u4e48\u5c31\u4f1a\u629b\u51fa\u4e00\u4e2a\u5f02\u5e38\uff0c\u5f02\u5e38\u7684\u503c\u5c31\u662f\u5bf9\u5e94 <code>signal<\/code> \u7684 <code>reason<\/code> \u503c\u3002\u53ef\u4ee5\u770b\u4e0b\u9762\u7684\u4ee3\u7801\u4f8b\u5b50\uff1a<\/p>\n<pre><code class=\"javascript\">const signal = AbortSignal.abort();\nsignal.throwIfAborted();\n\n\/\/ try {\n\/\/   signal.throwIfAborted();\n\/\/ } catch (e) {\n\/\/   console.log(e);\n\/\/ }\n<\/code><\/pre>\n<p>\u8fd0\u884c\u540e\u5728\u63a7\u5236\u53f0\u7684\u8f93\u51fa\u5982\u4e0b\uff1a<\/p>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/bVc2gEc\" alt=\"14\" title=\"14\" loading=\"lazy\"><\/p>\n<p>\u53ef\u4ee5\u770b\u5230\u76f4\u63a5\u629b\u51fa\u5f02\u5e38\uff0c\u8fd9\u4e2a\u65f6\u5019\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7 <code>try ... catch ...<\/code> \u8fdb\u884c\u6355\u83b7\uff0c\u7136\u540e\u518d\u8fdb\u884c\u5bf9\u5e94\u7684\u903b\u8f91\u5904\u7406\u3002\u8fd9\u4e2a\u65b9\u6cd5\u4e5f\u662f\u5f88\u6709\u5e2e\u52a9\u7684\uff0c\u6211\u4eec\u5728\u540e\u9762\u4f1a\u8bb2\u5230\u3002\u5f53\u6211\u4eec\u5b9e\u73b0\u4e00\u4e2a\u81ea\u5b9a\u4e49\u7684\u53ef\u4ee5\u4e3b\u52a8\u53d6\u6d88\u7684 <code>Promise<\/code> \u7684\u65f6\u5019\u8fd9\u4e2a\u65b9\u6cd5\u5c31\u5f88\u6709\u7528\u3002<\/p>\n<h5>\u4e8b\u4ef6\u76d1\u542c abort<\/h5>\n<p>\u5bf9\u4e8e <code>signal<\/code> \u5bf9\u8c61\u6765\u8bf4\uff0c\u5b83\u8fd8\u53ef\u4ee5\u76d1\u542c <code>abort<\/code> \u4e8b\u4ef6\uff0c\u7136\u540e\u6211\u4eec\u5c31\u53ef\u4ee5\u5728 <code>signal<\/code> \u88ab\u7ec8\u6b62\u7684\u65f6\u5019\u505a\u4e00\u4e9b\u989d\u5916\u7684\u64cd\u4f5c\u3002\u4e0b\u9762\u662f\u4e8b\u4ef6\u76d1\u542c\u7684\u7b80\u5355\u4f8b\u5b50\uff1a<\/p>\n<pre><code class=\"javascript\">const ac = new AbortController();\nconst { signal } = ac;\n\n\/\/ \u6dfb\u52a0\u4e8b\u4ef6\u76d1\u542c\nsignal.addEventListener('abort', function (e) {\n  console.log('signal is aborted');\n  console.warn(e);\n});\n\nsetTimeout(() =&gt; {\n  ac.abort();\n}, 100);\n<\/code><\/pre>\n<p>\u8fd0\u884c\u540e\u5728\u63a7\u5236\u53f0\u7684\u8f93\u51fa\u5982\u4e0b\uff1a<\/p>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/bVc2gEd\" alt=\"15\" title=\"15\" loading=\"lazy\"><\/p>\n<p>\u53ef\u4ee5\u770b\u5230\u5728 <code>signal<\/code> \u88ab\u7ec8\u6b62\u7684\u65f6\u5019\uff0c\u6211\u4eec\u4e4b\u524d\u6dfb\u52a0\u7684\u4e8b\u4ef6\u76d1\u542c\u51fd\u6570\u5c31\u5f00\u59cb\u8fd0\u884c\u4e86\u3002\u5176\u4e2d <code>e<\/code> \u8868\u793a\u7684\u662f\u63a5\u6536\u5230\u7684\u4e8b\u4ef6\u5bf9\u8c61\uff0c\u7136\u540e\u8fd9\u4e2a\u4e8b\u4ef6\u5bf9\u8c61\u4e0a\u7684 <code>target<\/code> \u548c <code>currentTarget<\/code> \u8868\u793a\u7684\u5c31\u662f\u5bf9\u5e94\u7684 <code>signal<\/code> \u5bf9\u8c61\u3002<\/p>\n<h4>\u5b9e\u73b0\u4e00\u4e2a\u53ef\u4ee5\u4e3b\u52a8\u53d6\u6d88\u7684 Promise<\/h4>\n<p>\u5f53\u6211\u4eec\u5bf9 <code>AbortController<\/code> \u4ee5\u53ca <code>AbortSignal<\/code> \u6bd4\u8f83\u719f\u6089\u7684\u65f6\u5019\uff0c\u6211\u4eec\u5c31\u53ef\u4ee5\u5f88\u65b9\u4fbf\u7684\u6784\u9020\u51fa\u6211\u4eec\u81ea\u5b9a\u4e49\u7684\u53ef\u4ee5\u53d6\u6d88\u7684 <code>Promise<\/code> \u4e86\u3002\u4e0b\u9762\u5c31\u662f\u4e00\u4e2a\u6bd4\u8f83\u7b80\u5355\u7684\u7248\u672c\uff0c\u5927\u5bb6\u53ef\u4ee5\u770b\u4e00\u4e0b\uff1a<\/p>\n<pre><code class=\"javascript\">\/**\n * \u81ea\u5b9a\u4e49\u7684\u53ef\u4ee5\u4e3b\u52a8\u53d6\u6d88\u7684 Promise\n *\/\n\nfunction myCoolPromise ({ signal }) {\n  return new Promise((resolve, reject) =&gt; {\n    \/\/ \u5982\u679c\u521a\u5f00\u59cb signal \u5b58\u5728\u5e76\u4e14\u662f\u7ec8\u6b62\u7684\u72b6\u6001\u53ef\u4ee5\u76f4\u63a5\u629b\u51fa\u5f02\u5e38\n    signal?.throwIfAborted();\n\n    \/\/ \u5f02\u6b65\u7684\u64cd\u4f5c\uff0c\u8fd9\u91cc\u4f7f\u7528 setTimeout \u6a21\u62df\n    setTimeout(() =&gt; {\n      Math.random() &gt; 0.5 ? resolve('ok') : reject(new Error('not good'));\n    }, 1000);\n\n    \/\/ \u6dfb\u52a0 abort \u4e8b\u4ef6\u76d1\u542c\uff0c\u4e00\u65e6 signal \u72b6\u6001\u6539\u53d8\u5c31\u5c06 Promise \u7684\u72b6\u6001\u6539\u53d8\u4e3a rejected\n    signal?.addEventListener('abort', () =&gt; reject(signal?.reason));\n  });\n}\n\n\/**\n * \u4f7f\u7528\u81ea\u5b9a\u4e49\u53ef\u53d6\u6d88\u7684 Promise\n *\/\n\nconst ac = new AbortController();\nconst { signal } = ac;\n\nmyCoolPromise({ signal }).then((res) =&gt; console.log(res), err =&gt; console.warn(err));\nsetTimeout(() =&gt; {\n  ac.abort();\n}, 100); \/\/ \u53ef\u4ee5\u66f4\u6539\u65f6\u95f4\u770b\u4e0d\u540c\u7684\u7ed3\u679c\n<\/code><\/pre>\n<p>\u8fd9\u6b21\u7684\u4ee3\u7801\u7a0d\u5fae\u591a\u4e86\u4e00\u70b9\uff0c\u4e0d\u8fc7\u76f8\u4fe1\u5927\u5bb6\u8fd8\u662f\u5f88\u5bb9\u6613\u5c31\u77e5\u9053\u4e0a\u9762\u7684\u4ee3\u7801\u8981\u8868\u793a\u7684\u662f\u4ec0\u4e48\u610f\u601d\u3002<\/p>\n<p>\u9996\u5148\u6211\u4eec\u81ea\u5b9a\u4e49\u4e86 <code>myCoolPromise<\/code> \u8fd9\u4e2a\u51fd\u6570\uff0c\u7136\u540e\u51fd\u6570\u63a5\u6536\u4e00\u4e2a\u975e\u5fc5\u4f20\u7684 <code>signal<\/code> \u5bf9\u8c61\uff1b\u7136\u540e\u7acb\u5373\u8fd4\u56de\u4e00\u4e2a\u65b0\u6784\u5efa\u7684 <code>Promise<\/code>\uff0c\u8fd9\u4e2a <code>Promise<\/code> \u7684\u5185\u90e8\u6211\u4eec\u6dfb\u52a0\u4e86\u4e00\u4e9b\u989d\u5916\u7684\u5904\u7406\u3002\u9996\u5148\u6211\u4eec\u5224\u65ad\u4e86 <code>signal<\/code> \u662f\u5426\u5b58\u5728\uff0c\u5982\u679c\u5b58\u5728\u5c31\u8c03\u7528\u5b83\u7684 <code>throwIfAborted<\/code> \u65b9\u6cd5\u3002\u56e0\u4e3a\u6709\u53ef\u80fd\u8fd9\u4e2a\u65f6\u5019 <code>signal<\/code> \u7684\u72b6\u6001\u5df2\u7ecf\u662f\u7ec8\u6b62\u7684\u72b6\u6001\u4e86\uff0c\u9700\u8981\u7acb\u5373\u5c06 <code>Promise<\/code> \u7684\u72b6\u6001\u53d8\u66f4\u4e3a <code>rejected<\/code> \u72b6\u6001\u3002<\/p>\n<p>\u5982\u679c\u6b64\u65f6 <code>signal<\/code> \u7684\u72b6\u6001\u8fd8\u6ca1\u6709\u6539\u53d8\uff0c\u90a3\u4e48\u6211\u4eec\u53ef\u4ee5\u7ed9\u8fd9\u4e2a <code>signal<\/code> \u6dfb\u52a0\u4e00\u4e2a\u4e8b\u4ef6\u76d1\u542c\uff0c\u4e00\u65e6 <code>signal<\/code> \u7684\u72b6\u6001\u6539\u53d8\uff0c\u6211\u4eec\u5c31\u9700\u8981\u7acb\u5373\u53bb\u6539\u53d8 <code>Promise<\/code> \u7684\u72b6\u6001\u3002<\/p>\n<p>\u5f53\u6211\u4eec\u4e0b\u9762\u7684 <code>setTimeout<\/code> \u7684\u65f6\u95f4\u8bbe\u7f6e\u4e3a100\u6beb\u79d2\u7684\u65f6\u5019\uff0c\u4e0a\u9762\u7684 <code>Promise<\/code> \u603b\u662f\u62d2\u7edd\u7684\u72b6\u6001\uff0c\u6240\u4ee5\u4f1a\u770b\u5230\u63a7\u5236\u53f0\u7684\u6253\u5370\u7ed3\u679c\u5982\u4e0b\uff1a<\/p>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/bVc2gEe\" alt=\"16\" title=\"16\" loading=\"lazy\"><\/p>\n<p>\u5982\u679c\u6211\u4eec\u628a\u8fd9\u4e2a\u65f6\u95f4\u4fee\u6539\u4e3a<strong>2000\u6beb\u79d2<\/strong>\u7684\u8bdd\uff0c\u90a3\u4e48\u63a7\u5236\u53f0\u8f93\u51fa\u7684\u7ed3\u679c\u53ef\u80fd\u662f <strong>ok<\/strong> \u4e5f\u53ef\u80fd\u662f\u4e00\u4e2a <strong>not good<\/strong> \u7684\u5f02\u5e38\u6355\u83b7\u3002<\/p>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/bVc2gEg\" alt=\"17\" title=\"17\" loading=\"lazy\"><br \/><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/bVc2gEj\" alt=\"18\" title=\"18\" loading=\"lazy\"><\/p>\n<p>\u6709\u540c\u5b66\u770b\u5230\u8fd9\u91cc\u53ef\u80fd\u4f1a\u8bf4\uff0c\u597d\u50cf\u4e0d\u9700\u8981 <code>signal<\/code> \u4e5f\u53ef\u4ee5\u5b9e\u73b0\u4e3b\u52a8\u53d6\u6d88\u7684 <code>Promise<\/code>\uff0c\u6211\u53ef\u4ee5\u4f7f\u7528\u4e00\u4e2a\u666e\u901a\u7684 <code>EventTarget<\/code> \u7ed3\u5408 <code>CustomEvent<\/code> \u4e5f\u53ef\u4ee5\u5b9e\u73b0\u7c7b\u4f3c\u7684\u6548\u679c\u3002\u5f53\u7136\u6211\u4eec\u4e5f\u53ef\u4ee5\u8fd9\u6837\u505a\uff0c\u4f46\u662f\u4e00\u822c\u60c5\u51b5\u4e0b\u6211\u4eec\u7684\u5f02\u6b65\u64cd\u4f5c\u662f\u5305\u542b\u7f51\u7edc\u8bf7\u6c42\u7684\uff0c\u5982\u679c\u7f51\u7edc\u8bf7\u6c42\u4f7f\u7528\u7684\u662f <code>fetch<\/code> \u65b9\u6cd5\u7684\u8bdd\uff0c\u90a3\u4e48\u5c31\u5fc5\u987b\u4f7f\u7528 <code>AbortSignal<\/code> \u7c7b\u578b\u7684\u5b9e\u4f8b <code>signal<\/code> \u8fdb\u884c\u4fe1\u53f7\u7684\u4f20\u9012\uff1b\u56e0\u4e3a <code>fetch<\/code> \u65b9\u6cd5\u5185\u90e8\u4f1a\u6839\u636e <code>signal<\/code> \u7684\u72b6\u6001\u6765\u5224\u65ad\u5230\u5e95\u9700\u4e0d\u9700\u8981\u7ec8\u6b62\u6b63\u5728\u8fdb\u884c\u7684\u8bf7\u6c42\u3002<\/p>\n<p><code>AbortSignal<\/code> \u7684\u76f8\u5173\u5c5e\u6027\u548c\u65b9\u6cd5\uff1a<\/p>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/bVc2gEk\" alt=\"19\" title=\"19\" loading=\"lazy\"><\/p>\n<h3>\u5f00\u53d1\u4e2d\u5176\u4ed6\u573a\u666f\u7684\u4f7f\u7528\u4e3e\u4f8b<\/h3>\n<h4>\u53d6\u6d88\u4e8b\u4ef6\u76d1\u542c\u7684\u4e00\u79cd\u4fbf\u6377\u65b9\u6cd5<\/h4>\n<p>\u4e00\u822c\u60c5\u51b5\u4e0b\uff0c\u5982\u679c\u6211\u4eec\u5bf9\u6587\u6863\u4e2d\u7684\u67d0\u4e2a <strong>DOM<\/strong> \u5143\u7d20\u6dfb\u52a0\u4e86\u4e8b\u4ef6\u76d1\u542c\uff0c<strong>\u90a3\u4e48\u5f53\u8fd9\u4e2a\u5143\u7d20\u88ab\u9500\u6bc1\u6216\u8005\u79fb\u9664\u7684\u65f6\u5019\uff0c\u4e5f\u9700\u8981\u76f8\u5e94\u7684\u628a\u5bf9\u5e94\u7684\u4e8b\u4ef6\u76d1\u542c\u51fd\u6570\u79fb\u9664\u6389\uff0c\u4e0d\u7136\u5f88\u5bb9\u6613\u51fa\u73b0\u5185\u5b58\u6cc4\u6f0f\u7684\u95ee\u9898<\/strong>\u3002\u6240\u4ee5\u4e00\u822c\u60c5\u51b5\u4e0b\u6211\u4eec\u4f1a\u6309\u7167\u4e0b\u9762\u7684\u65b9\u5f0f\u6dfb\u52a0\u5e76\u4e14\u79fb\u9664\u76f8\u5173\u7684\u4e8b\u4ef6\u76d1\u542c\u51fd\u6570\u3002<\/p>\n<pre><code class=\"html\">&lt;button class=&quot;event&quot;&gt;\u4e8b\u4ef6\u76d1\u542c\u6309\u94ae&lt;\/button&gt;\n&lt;button class=&quot;cancel&quot;&gt;\u70b9\u51fb\u540e\u53d6\u6d88\u4e8b\u4ef6\u76d1\u542c&lt;\/button&gt;<\/code><\/pre>\n<pre><code class=\"javascript\">const evtBtn = document.querySelector('.event');\nconst cancelBtn = document.querySelector('.cancel');\n\nconst evtHandler = (e) =&gt; {\n  console.log(e);\n};\nevtBtn.addEventListener('click', evtHandler);\n\/\/ \u70b9\u51fb cancelBtn \u79fb\u9664 evtBtn \u6309\u94ae\u7684 click \u4e8b\u4ef6\u76d1\u542c\ncancelBtn.addEventListener('click', function () {\n  evtBtn.removeEventListener('click', evtHandler);\n});\n<\/code><\/pre>\n<p>\u8fd9\u79cd\u65b9\u5f0f\u662f\u6700\u901a\u7528\u7684\u65b9\u5f0f\uff0c\u4f46\u662f\u8fd9\u79cd\u65b9\u5f0f\u9700\u8981\u6211\u4eec\u4fdd\u7559\u5bf9\u5e94\u4e8b\u4ef6\u76d1\u542c\u51fd\u6570\u7684\u5f15\u7528\uff0c\u6bd4\u5982\u4e0a\u9762\u7684 <code>evtHandler<\/code>\u3002\u4e00\u65e6\u6211\u4eec\u4e22\u5931\u4e86\u8fd9\u4e2a\u5f15\u7528\uff0c\u90a3\u4e48\u540e\u9762\u5c31\u6ca1\u6709\u529e\u6cd5\u53d6\u6d88\u8fd9\u4e2a\u4e8b\u4ef6\u76d1\u542c\u4e86\u3002<\/p>\n<p>\u53e6\u5916\uff0c\u6709\u4e9b\u5e94\u7528\u573a\u666f\u9700\u8981\u4f60\u7ed9\u67d0\u4e2a\u5143\u7d20\u6dfb\u52a0\u5f88\u591a\u4e8b\u4ef6\u5904\u7406\u51fd\u6570\uff0c\u53d6\u6d88\u7684\u65f6\u5019\u5c31\u9700\u8981\u4e00\u4e2a\u4e00\u4e2a\u53bb\u53d6\u6d88\uff0c\u5f88\u4e0d\u65b9\u4fbf\u3002\u8fd9\u4e2a\u65f6\u5019\u6211\u4eec\u7684 <code>AbortSignal<\/code> \u5c31\u53ef\u4ee5\u6d3e\u4e0a\u7528\u573a\u4e86\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 <code>AbortSignal<\/code> \u6765\u540c\u65f6\u53d6\u6d88\u5f88\u591a\u4e8b\u4ef6\u7684\u4e8b\u4ef6\u76d1\u542c\u51fd\u6570\u3002\u5c31\u50cf\u6211\u4eec\u540c\u65f6\u53d6\u6d88\u5f88\u591a\u4e2a <code>fetch<\/code> \u8bf7\u6c42\u4e00\u6837\u3002\u4ee3\u7801\u5982\u4e0b\uff1a<\/p>\n<pre><code class=\"javascript\">\/\/ ... HTML \u90e8\u5206\u53c2\u8003\u4e0a\u9762\u7684\u5185\u5bb9\n\nconst evtBtn = document.querySelector('.event');\nconst cancelBtn = document.querySelector('.cancel');\n\nconst evtHandler = (e) =&gt; console.log(e);\nconst mdHandler = (e) =&gt; console.log(e);\nconst muHandler = (e) =&gt; console.log(e);\n\nconst ac = new AbortController();\nconst { signal } = ac;\n\nevtBtn.addEventListener('click', evtHandler, { signal });\nevtBtn.addEventListener('mousedown', mdHandler, { signal });\nevtBtn.addEventListener('mouseup', muHandler, { signal });\n\n\/\/ \u70b9\u51fb cancelBtn \u79fb\u9664 evtBtn \u6309\u94ae\u7684 click \u4e8b\u4ef6\u76d1\u542c\ncancelBtn.addEventListener('click', function () {\n  ac.abort();\n});\n<\/code><\/pre>\n<p>\u8fd9\u6837\u7684\u5904\u7406\u65b9\u5f0f\u662f\u4e0d\u662f\u5c31\u5f88\u65b9\u4fbf\uff0c\u4e5f\u975e\u5e38\u7684\u6e05\u695a\u660e\u4e86\u3002<\/p>\n<pre><code class=\"javascript\">addEventListener(type, listener, options);<\/code><\/pre>\n<p><code>addEventListener<\/code> \u7684\u7b2c\u4e09\u4e2a\u53c2\u6570\u53ef\u4ee5\u662f\u4e00\u4e2a <code>options<\/code> \u5bf9\u8c61\uff0c\u8fd9\u4e2a\u5bf9\u8c61\u53ef\u4ee5\u8ba9\u6211\u4eec\u4f20\u9012\u4e00\u4e2a <code>signal<\/code> \u5bf9\u8c61\u7528\u6765\u4f5c\u4e3a\u4e8b\u4ef6\u53d6\u6d88\u7684\u4fe1\u53f7\u5bf9\u8c61\u3002\u5c31\u50cf\u4e0a\u9762\u6211\u4eec\u4f7f\u7528 <code>signal<\/code> \u5bf9\u8c61\u6765\u53d6\u6d88 <code>fetch<\/code> \u8bf7\u6c42\u90a3\u6837\u3002<\/p>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/bVc2gEl\" alt=\"20\" title=\"20\" loading=\"lazy\"><\/p>\n<p>\u4ece\u4e0a\u9762\u7684\u517c\u5bb9\u6027\u6765\u8bf4\uff0c\u8fd9\u4e2a\u5c5e\u6027\u7684\u517c\u5bb9\u6027\u8fd8\u662f\u53ef\u4ee5\u7684\uff1b\u76ee\u524d\u53ea\u6709 <strong>Opera Android<\/strong> \u548c <strong>Node.js<\/strong> \u6682\u65f6\u8fd8\u4e0d\u652f\u6301\uff0c\u5982\u679c\u60f3\u8981\u4f7f\u7528\u8fd9\u4e2a\u65b0\u7684\u5c5e\u6027\uff0c\u9700\u8981\u9488\u5bf9\u8fd9\u4e24\u4e2a\u5e73\u53f0\u548c\u8fd0\u884c\u73af\u5883\u505a\u4e00\u4e0b\u517c\u5bb9\u5904\u7406\u5c31\u597d\u4e86\u3002<\/p>\n<h4>\u4e00\u79cd\u503c\u5f97\u501f\u9274\u7684\u5904\u7406\u590d\u6742\u4e1a\u52a1\u903b\u8f91\u7684\u65b9\u6cd5<\/h4>\n<p>\u6211\u4eec\u6709\u65f6\u5f00\u53d1\u4e2d\u4f1a\u9047\u5230\u4e00\u4e9b\u6bd4\u8f83\u590d\u6742\u7684\u5904\u7406\u64cd\u4f5c\uff0c\u6bd4\u5982\u4f60\u8981\u5148\u901a\u8fc7\u597d\u51e0\u4e2a\u63a5\u53e3\u83b7\u53d6\u6570\u636e\uff0c\u7136\u540e\u7ec4\u88c5\u6570\u636e\uff1b\u7136\u540e\u518d\u628a\u8fd9\u4e9b\u6570\u636e\u5f02\u6b65\u5730\u7ed8\u5236\u6e32\u67d3\u5230\u9875\u9762\u4e0a\u3002\u5982\u679c\u7528\u6237\u4e3b\u52a8\u53d6\u6d88\u4e86\u8fd9\u4e2a\u64cd\u4f5c\u6216\u8005\u56e0\u4e3a\u8d85\u65f6\u4e86\uff0c\u6211\u4eec\u8981\u4e3b\u52a8\u53d6\u6d88\u8fd9\u4e9b\u64cd\u4f5c\u3002\u5bf9\u4e8e\u8fd9\u79cd\u573a\u666f\uff0c\u4f7f\u7528 <code>AbortController<\/code> \u914d\u5408 <code>AbortSignal<\/code> \u4e5f\u6709\u4e0d\u9519\u7684\u6548\u679c\uff0c\u4e0b\u9762\u4e3e\u4e00\u4e2a\u7b80\u5355\u7684\u4f8b\u5b50\uff1a<\/p>\n<pre><code class=\"javascript\">\/\/ \u591a\u4e2a\u4e32\u884c\u6216\u8005\u5e76\u884c\u7684\u7f51\u7edc\u8bf7\u6c42\nconst requestUserData = (signal) =&gt; {\n  \/\/ TODO\n};\n\/\/ \u5f02\u6b65\u7684\u7ed8\u5236\u6e32\u67d3\u64cd\u4f5c \u91cc\u9762\u5305\u542b\u4e86 Promise \u7684\u5904\u7406\nconst drawAndRenderImg = (signal) =&gt; {\n  \/\/ TODO\n};\n\/\/ \u83b7\u53d6\u670d\u52a1\u7aef\u6570\u636e\u5e76\u4e14\u8fdb\u884c\u6570\u636e\u7684\u7ed8\u5236\u548c\u6e32\u67d3\nfunction fetchServerDataAndDrawImg ({ signal }) {\n  signal?.throwIfAborted();\n  \/\/ \u591a\u4e2a\u7f51\u7edc\u8bf7\u6c42\n  requestUserData(signal);\n  \/\/ \u7ec4\u88c5\u6570\u636e\uff0c\u5f00\u59cb\u7ed8\u5236\u548c\u6e32\u67d3\n  drawAndRenderImg(signal);\n  \/\/ ... \u4e00\u4e9b\u5176\u4ed6\u7684\u64cd\u4f5c\n}\n\nconst ac = new AbortController();\nconst { signal } = ac;\n\ntry {\n  fetchServerDataAndDrawImg({ signal });\n} catch (e) {\n  console.warn(e);\n}\n\n\/\/ \u7528\u6237\u4e3b\u52a8\u53d6\u6d88\u6216\u8005\u8d85\u65f6\u53d6\u6d88\nsetTimeout(() =&gt; {\n  ac.abort();\n}, 2000);\n<\/code><\/pre>\n<p>\u4e0a\u9762\u662f\u4e00\u4e2a\u7b80\u5316\u7684\u4f8b\u5b50\uff0c\u7528\u6765\u8868\u793a\u8fd9\u79cd\u590d\u6742\u7684\u64cd\u4f5c\uff1b\u6211\u4eec\u53ef\u4ee5\u770b\u5230\uff0c\u5982\u679c\u7528\u6237\u4e3b\u52a8\u53d6\u6d88\u6216\u8005\u56e0\u4e3a\u8d85\u65f6\u53d6\u6d88\u64cd\u4f5c\uff1b\u6211\u4eec\u4e0a\u9762\u7684\u4ee3\u7801\u903b\u8f91\u53ef\u4ee5\u5f88\u65b9\u4fbf\u7684\u5904\u7406\u8fd9\u79cd\u60c5\u51b5\u3002\u4e5f\u4e0d\u4f1a\u56e0\u4e3a\u5c11\u5904\u7406\u4e86\u4e00\u4e9b\u64cd\u4f5c\u800c\u5bfc\u81f4\u53ef\u80fd\u53d1\u751f\u7684\u5185\u5b58\u6cc4\u6f0f\u3002<\/p>\n<p>\u4e00\u65e6\u6211\u4eec\u60f3\u91cd\u65b0\u5f00\u59cb\u8fd9\u4e2a\u64cd\u4f5c\uff0c\u6211\u4eec\u53ea\u9700\u8981\u518d\u6b21\u8c03\u7528 <code>fetchServerDataAndDrawImg<\/code> \u5e76\u4e14\u4f20\u9012\u4e00\u4e2a\u65b0\u7684 <code>signal<\/code> \u5bf9\u8c61\u5c31\u53ef\u4ee5\u4e86\u3002\u8fd9\u6837\u5904\u7406\u540e\uff0c\u91cd\u65b0\u5f00\u59cb\u548c\u53d6\u6d88\u7684\u903b\u8f91\u5c31\u975e\u5e38\u6e05\u695a\u4e86\u3002\u5982\u679c\u5927\u5bb6\u5728\u81ea\u5df1\u7684\u9879\u76ee\u4e2d\u6709\u7c7b\u4f3c\u7684\u8fd9\u79cd\u64cd\u4f5c\uff0c\u4e0d\u59a8\u53ef\u4ee5\u8bd5\u8bd5\u8fd9\u79cd\u5904\u7406\u65b9\u6cd5\u3002<\/p>\n<h4>\u5728 Node.js \u4e2d\u7684\u4f7f\u7528<\/h4>\n<p>\u6211\u4eec\u4e0d\u4ec5\u53ef\u4ee5\u5728\u6d4f\u89c8\u5668\u73af\u5883\u4e2d\u4f7f\u7528 <code>AbortController<\/code> \u548c <code>AbortSignal<\/code>\uff0c\u8fd8\u53ef\u4ee5\u5728 <code>Node.js<\/code> \u73af\u5883\u4e2d\u4f7f\u7528\u8fd9\u4e24\u4e2a\u529f\u80fd\u3002\u5bf9\u4e8e <code>Node.js<\/code> \u4e2d\u7684 <code>fs.readFile<\/code>\uff0c<code>fs.writeFile<\/code>\uff0c<code>http.request<\/code>\uff0c<code>https.request<\/code> \u548c <code>timers<\/code> \u4ee5\u53ca\u65b0\u7248\u672c\u652f\u6301\u7684 <code>Fetch API<\/code> \u90fd\u53ef\u4ee5\u4f7f\u7528 <code>signal<\/code> \u6765\u8fdb\u884c\u64cd\u4f5c\u7684\u53d6\u6d88\u3002\u4e0b\u9762\u6211\u4eec\u6765\u4e3e\u4e00\u4e2a\u7b80\u5355\u7684\u4f8b\u5b50\uff0c\u5173\u4e8e\u8bfb\u53d6\u6587\u4ef6\u7684\u64cd\u4f5c\uff1a<\/p>\n<pre><code class=\"javascript\">const fs = require('fs');\n\nconst ac = new AbortController();\nconst { signal } = ac;\n\nfs.readFile('data.json', { signal, encoding: 'utf8' }, (err, data) =&gt; {\n  if (err) {\n    console.error(err);\n    return;\n  }\n  console.log(data);\n});\n\nac.abort();\n<\/code><\/pre>\n<p>\u8fd0\u884c\u4ee3\u7801\u53ef\u4ee5\u770b\u5230\u7ec8\u7aef\u7684\u8f93\u51fa\u5982\u4e0b\uff1a<\/p>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/bVc2gEm\" alt=\"21\" title=\"21\" loading=\"lazy\"><\/p>\n<p>\u7ecf\u5e38\u4f7f\u7528 <code>Node.js<\/code> \u8fdb\u884c\u4e1a\u52a1\u5f00\u53d1\u7684\u540c\u5b66\u53ef\u4ee5\u5c1d\u8bd5\u4f7f\u7528\u8fd9\u4e2a\u65b0\u7684\u7279\u6027\uff0c\u5e94\u8be5\u5bf9\u5f00\u53d1\u4f1a\u5f88\u6709\u5e2e\u52a9\u7684\u3002<\/p>\n<h3>\u53cd\u9988\u548c\u5efa\u8bae<\/h3>\n<p>\u8fd9\u7bc7\u6587\u7ae0\u5230\u8fd9\u91cc\u5c31\u7b97\u7ed3\u675f\u5566\uff0c\u4e0d\u77e5\u9053\u6709\u591a\u5c11\u540c\u5b66\u575a\u6301\u8bfb\u5b8c\u4e86\u8fd9\u7bc7\u6587\u7ae0\uff1b\u5e0c\u671b\u8bfb\u5b8c\u7684\u540c\u5b66\u90fd\u80fd\u591f\u638c\u63e1\u597d\u8fd9\u7bc7\u6587\u7ae0\u4e2d\u8bb2\u89e3\u7684\u77e5\u8bc6\u3002\u5982\u679c\u8fd9\u7bc7\u6587\u7ae0\u5e2e\u5230\u4e86\u4f60\uff0c\u6216\u8005\u6253\u5f00\u4e86\u4f60\u7684\u65b0\u4e16\u754c\uff1b\u6b22\u8fce\u70b9\u8d5e\u8f6c\u53d1\u3002<\/p>\n<p>\u5982\u679c\u4f60\u5bf9\u8fd9\u7bc7\u6587\u7ae0\u6709\u4ec0\u4e48\u5efa\u8bae\u548c\u610f\u89c1\uff0c\u6b22\u8fce\u5927\u5bb6\u5728\u6587\u7ae0\u4e0b\u9762\u7559\u8a00\u8bc4\u8bba\uff0c\u6211\u4eec\u4e00\u8d77\u8ba8\u8bba\u4e00\u4e0b\uff0c\u4e00\u8d77\u8fdb\u6b65\u5440\u3002<\/p>\n<h4>\u5f80\u671f\u7cbe\u5f69\u63a8\u8350<\/h4>\n<ul>\n<li><a href=\"https:\/\/www.bilibili.com\/video\/BV1JY4y1A7CT?share_source=copy_web&#038;vd_source=b871b2f283babd6b02f4a1141a90cb5b\">\u3010\u524d\u7aef\u5c0f\u8bfe\u5802004 &#8211; \u5982\u4f55\u5199\u4e00\u4e2a\u62d6\u57ae\u4f60\u9875\u9762\u6027\u80fd\u7684\u6b63\u5219\u8868\u8fbe\u5f0f\u3011<\/a><\/li>\n<li><a href=\"https:\/\/www.bilibili.com\/video\/BV1sB4y1k7uG?share_source=copy_web&#038;vd_source=b871b2f283babd6b02f4a1141a90cb5b\">\u3010\u524d\u7aef\u5c0f\u8bfe\u5802003 &#8211; \u5c11\u5e74\uff0c\u4e0d\u6765\u8bd5\u8bd5\u7528\u6b63\u5219\u5904\u7406\u6570\u5b57\u7684\u5343\u5206\u4f4d\u5417\uff1f\u3011<\/a><\/li>\n<li><a href=\"https:\/\/www.bilibili.com\/video\/BV1qB4y1W7zX?share_source=copy_web&#038;vd_source=b871b2f283babd6b02f4a1141a90cb5b\">\u3010\u524d\u7aef\u5c0f\u8bfe\u5802002 &#8211; JavaScript\u5982\u4f55\u5e8f\u5217\u5316\u542b\u6709\u5faa\u73af\u5f15\u7528\u7684\u5bf9\u8c61\u3011<\/a><\/li>\n<li>\n<p><a href=\"https:\/\/www.bilibili.com\/video\/BV1N94y1R7bk?share_source=copy_web&#038;vd_source=b871b2f283babd6b02f4a1141a90cb5b\">\u3010\u524d\u7aef\u5c0f\u8bfe\u5802001 &#8211; WeakMap\u4e00\u70b9\u4e5f\u4e0dweak\u3011<\/a><\/p>\n<h4>\u53c2\u8003\u7684\u76f8\u5173\u7f51\u5740<\/h4>\n<\/li>\n<li><a href=\"https:\/\/link.segmentfault.com\/?enc=fBsPI%2FjF5eD8s4s%2FOGvmJw%3D%3D.F3sgFgmZ8QjixXBQEL842dfE8eHXt6CYR%2FOwLgdIVA%2FSJ1ZhOVhEP9ieFwkdx19qyWL3h7MSjoWKNXHsI4uhpRyVTXrtKZL0TQ3YVzIYOBE%3D\" rel=\"nofollow\">MDN &#8211; AbortController<\/a><\/li>\n<li><a href=\"https:\/\/link.segmentfault.com\/?enc=i1Coc4LnXtlzuijW1qHlqA%3D%3D.wdLDfnTC3K7rRdyFgDnVgX8jZdHSdv644gxdKS2ezcpEhw7Hmbh61MgEWjgLJPrM\" rel=\"nofollow\">DOM Living Standard &#8211; Interface AbortController<\/a><\/li>\n<li><a href=\"https:\/\/link.segmentfault.com\/?enc=mOCAxIlKUwctPm5UT0QBWQ%3D%3D.TYCLTTwoo%2BjxK2b%2BicvL%2BZHk4hBMVo%2B44H34MwPp0%2BGqfxYGrLEMFmt0HriQ%2BTqjsBSM6%2BdCiRRugfsP50nwhg%3D%3D\" rel=\"nofollow\">How to Cancel Promise with AbortController<\/a><\/li>\n<li><a href=\"https:\/\/link.segmentfault.com\/?enc=ajiPUi4X4lnYsmm1cqnTfg%3D%3D.gxh%2BqEbZIYt54vCYp6X7jXzC792KUEtniC1VmDqLsL6hJ9WV2GrgDi1VDuBVDfI5jWe41spJomuhGelJ1%2BbJVJN2fVbAUZFWqY8teaxzdUPRLflSISMONxsLLtNvGxvU\" rel=\"nofollow\">Using AbortController as an Alternative for Removing Event Listeners<\/a><\/li>\n<li><a href=\"https:\/\/link.segmentfault.com\/?enc=Guq6ElO1%2FVcO7hBsG7YCxA%3D%3D.r%2FaExokVD79yJR7ZAdY8CXOb0ksG6OyWhLUurLyrGrhqJpvAZZX%2Blu391EKl1dzG0tcOz6bacP%2BgV2LhWASAIEGYkf%2Bs%2FiN6v9DhRXGpCL8%3D\" rel=\"nofollow\">The complete guide to AbortController in Node.js<\/a><\/li>\n<li><a href=\"https:\/\/link.segmentfault.com\/?enc=3bi%2BytSXzXeub0fp9m89bA%3D%3D.nxHDmI6YPTsXJGx2D6hCUknfChdYjYIzwdakFFCfKQgIs70GfGxXyfmlPQ3P6dDJINfm93URVQM9e47r1fic8w%3D%3D\" rel=\"nofollow\">AbortController is your friend<\/a><\/li>\n<li><a href=\"https:\/\/link.segmentfault.com\/?enc=H1HiYVaWhb4hHS8YAbxJMg%3D%3D.4sSzkbv9AoudoRKYKbdMgPZMV4myCqo8AYNxh5%2FL6UsoVZVUjVqy2q1BjgiIWahq\" rel=\"nofollow\">Fetch: Abort<\/a><\/li>\n<li><a href=\"https:\/\/link.segmentfault.com\/?enc=hmWDJW9C3jmh5XTDyJ2TPg%3D%3D.apL%2B4UY3PEp1g%2Bk%2FEcBvtVkxj1LM8aSkwlz7EcjiroZyc0hK66dMO2ibWtzLdGQuEiOVaMBKdoJFgqHjqEEeyA%3D%3D\" rel=\"nofollow\">Abortable fetch<\/a><\/li>\n<li><a href=\"https:\/\/link.segmentfault.com\/?enc=7KzlWQqt24508paJi9FtDA%3D%3D.zuQ8QkalSvQ%2FbYEzj%2FkRr1B%2BgD8IR4elS1H4%2FljF5DL8x7CgmEiRRr3TOgvlkCAHrWrGsynXOd67QbbelNtWK3pkXmMm%2Bseq4mkCQZI5lAU%3D\" rel=\"nofollow\">EventTarget.addEventListener()<\/a><\/li>\n<li><a href=\"https:\/\/link.segmentfault.com\/?enc=wNivS%2BHJJSriCUBkAeYOOw%3D%3D.oaJtADOoRp%2BgbqB6uePjmTPOoAkEamoigjgw%2FIrQCuqVvi2jLdxPHWCiKcrojV5Sx9SGod2uwyGUBTDz0IGD%2BA%3D%3D\" rel=\"nofollow\">MDN &#8211; fetch()<\/a><\/li>\n<\/ul>\n<p><a href=\"https:\/\/segmentfault.com\/a\/1190000042447341\">https:\/\/segmentfault.com\/a\/1190000042447341<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u6b22\u8fce\u5927\u5bb6\u6765\u5230 \u524d\u7aef\u5c0f\u8bfe\u5802 \u7684\u7b2c\u4e94\u671f\uff0c\u4eca\u5929\u6211\u4eec\u6765\u804a\u4e00\u804a\u5982\u4f55\u7ec8\u6b62\u6b63\u5728\u8fdb\u884c\u4e2d\u7684 Fetch \u4ee5\u53ca Promise\u3002\u6587 [&hellip;]<\/p>\n","protected":false},"author":0,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[],"tags":[],"class_list":["post-10006425","post","type-post","status-publish","format-standard","hentry"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/itmax.cn\/index.php?rest_route=\/wp\/v2\/posts\/10006425","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/itmax.cn\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/itmax.cn\/index.php?rest_route=\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/itmax.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=10006425"}],"version-history":[{"count":0,"href":"https:\/\/itmax.cn\/index.php?rest_route=\/wp\/v2\/posts\/10006425\/revisions"}],"wp:attachment":[{"href":"https:\/\/itmax.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=10006425"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/itmax.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=10006425"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/itmax.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=10006425"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}