在使用 js 自带的 fecth 作网络请求时,没有提供例如$ajax 的超时选项,因此须要本身实现
多个fetch请求在网络不稳定的状况下,会占用大量内存,由于当网速很慢的状况下,fetch会一直等待,直到收到响应
javascript
使用Promise.race
, Promise.race 的做用是哪一个 Promise 先返回结果则最终输出这个 Promise 的返回值java
// 超时函数 const timeoutAction = timer => { return new Promise(reslove => { setTimeout(() => { // 实例化超时响应json数据 const response = new Response( JSON.stringify({ code: 1, msg: `timeout ${timer}s` }) ); return reslove(response); }, timer * 1000); }); }; const url = "/data.json"; // 请求的url // 执行,超时控制在0秒,让它永远超时,方便观察 Promise.race([timeoutAction(0), fetch(url)]) .then(res => { return res.json(); }) .then(res => { if (res.code !== 0) { return alert(res.msg); } else { return console.log(res); } });
上述代码只是让浏览器直到已经超时,而实际上的fetch请求还在继续,因此要多作一步操做, 在超时的时候手动终止fetch请求
AbortController 用于手动终止一个或多个DOM请求,经过该对象的AbortSignal注入的Fetch的请求中。因此须要完美实现timeout功能加上这个就对了
ajax
let controller = new AbortController(); let signal = controller.signal; // 超时函数 const timeoutAction = timer => { return new Promise(reslove => { setTimeout(() => { // 实例化超时响应json数据 const response = new Response( JSON.stringify({ code: 1, msg: `timeout ${timer}s` }) ); reslove(response); controller.abort(); // 发送终止信号 }, timer * 1000); }); }; const url = "/data.json"; // 请求的url // 执行,超时控制在0秒,让它永远超时,方便观察 Promise.race([ timeoutAction(0), fetch(url, { signal: signal //设置信号 }) ]) .then(res => { return res.json(); }) .then(res => { if (res.code !== 0) { return alert(res.msg); } else { return console.log(res); } });
当看到浏览器异步请求的状态值为canceled时,说明超时拦截成功
json