循环了6个框,每个框里有一个测试按钮和停止按钮. 怎么点击停止时,终止当前的fetch()请求
```javascript
<el-row :gutter="20" class="jianju" style="margin-left: 0px">
<el-col
:span="6"
:xs="24"
:sm="12"
:md="12"
:lg="8"
:xl="7"
class="bianju"
v-for="(item, index) in content"
:key="index"
>
<div class="grid-content bg-purple cont">
<el-button
class="tijiao"
type="primary"
@click="ceshi(index, item.type1)"
>{{ item.name }}
<el-button
class="tijiao"
style="float: right"
type="warning"
@click="ceshi(index)"
>停止
<div class="neirong">{{ item.value }}div>
div>
el-col>
el-row>
```javascript
ceshi(index) {
const controller = new AbortController();
const signal = controller.signal;
this.content[index].value = "";
let data = {
signal: signal,
method: "post",
headers: {
"Content-type": "application:/x-www-form-urlencoded:charset=UTF-8",
},
body: JSON.stringify({ request: "stream" }),
};
let url = " /api/serial" + (index + 1);
var self = this;
var f = (r) => {
return r.read().then((result) => {
var data = String.fromCharCode.apply(null, result.value);
self.content[index].value += data;
if (!result.done) f(r);
});
};
fetch(url, data)
.then((r) => r.body.getReader())
.then(f);
// setTimeout(() => {
// controller.abort();
// console.log(signal.aborted);
// }, 5000);
},
到目前为止,在浏览器里用 JavaScript 发起请求的方式有两种:XMLHttpRequest 和 fetch。XMLHttpRequest 我们比较熟悉,存在很长时间了,而 fetch 是 ES6 才引入的。
XMLHttpRequest 是可以中途取消的,如下所示:
let xhr = new XMLHttpRequest();xhr.method = 'GET';xhr.url = 'https://slowmo.glitch.me/5000';xhr.open(method, url, true);xhr.send();// 随后取消这个请求abortButton.addEventListener('click', function() { xhr.abort();});
fetch 刚开始引入的时候并不支持终止操作。最早的关于终止 fetch 请求的 GitHub issue 是在 2015 年提出的。在 fetch 规范之外,有不少解决这个问题的尝试,比如 cancelable-promises 和其他 hack 手段。
但是现在我们终于有了通用的AbortController 和 AbortSignal API。这些 API 是由 DOM 标准而不是语言本身提供的。
虽然 promise 没有内置的中断机制,很多使用它的 API 需要这个终止语义。AbortController就是通过提供abort() 方法切换相应 AbortSignal 对象的状态,从而满足这种需求的。想要支持终止功能的 API 可以接受一个AbortSignal 对象,然后根据它的状态决定如何继续。
// 创建 AbortController 实例const controller = new AbortController();const signal = controller.signal;// 监听 abort 信号, controller.abort() 执行时触发回调signal.addEventListener('abort', () => { console.log(signal.aborted); // true});// 稍后调用中止方法,发出信号controller.abort();
AbortController 用法
fetch 接受 AbortSignal作为第二个参数的一部分。
const controller = new AbortController();const signal = controller.signal;// 5s 后请求收到响应,注意第二个参数fetch('https://slowmo.glitch.me/5000', { signal }) .then(r => r.json()) .then(response => console.log(response)) .catch(err => { if (err.name === 'AbortError') { console.log('Fetch was aborted'); } else { console.error('Oops!', err); } });// 2秒后取消请求setTimeout(() => { controller.abort();}, 2000);
终止 fetch 会同时终止请求和响应,并抛出new DOMException('Aborted', 'AbortError')错误。另外,同一个 AbortSignal对象(上例中的signal)可以用于取消多个fetch请求。
还是用全局变量解决了问题.