關於 fetch
取消 Fetch
ES6以後Promise 出現解決地獄回調等不優雅的代碼風格。個人理解這個更像是一個生產者和消費者的關係,查看 Promise文檔,有以下兩個方法
- Promise.race([promise1,promise2]) 傳入多個Promise對象,等待最快對象完成
- Promise.all([promise1,promise2]) 傳入多個Promise 對象,等待所有對象完成
let timeoutPromise = (timeout) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("我是 timeoutPromise,已經完成了");
}, timeout);
});
}
let requestPromise = (url) => {
return fetch(url);
};
Promise.race([timeoutPromise(1000), requestPromise("https://www.baidu.com")])
.then(resp => {
console.log(resp);
})
.catch(error => {
console.log(error);
});
將上邊的代碼拷貝的瀏覽器控制檯並將network設置爲Slow3G。運行就會發現,雖然我們在控制檯看到了超時信息,但切換到netwok頁籤中發現請求依然正常進行中,並返回了正確的內容。這並不是我想要的結果,我希望超時時間到了,請求也應該終止。
fetch請求成功後,默認返回一個Response對象,那麼我們如何在代碼中構造一個這樣的對象呢?
timeoutResp=new Response("timeout", { status: 504, statusText: "timeout " })
successResp=new Response("ok", { status: 200, statusText: "ok " })
AbortController 用於手動終止一個或多個DOM請求,通過該對象的AbortSignal注入的Fetch的請求中。所以需要完美實現timeout功能加上這個就對了
let controller = new AbortController();
let signal = controller.signal;
let timeoutPromise = (timeout) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(new Response("timeout", { status: 504, statusText: "timeout " }));
controller.abort();
}, timeout);
});
}
let requestPromise = (url) => {
return fetch(url, {
signal: signal
});
};
Promise.race([timeoutPromise(1000), requestPromise("https://www.baidu.com")])
.then(resp => {
console.log(resp);
})
.catch(error => {
console.log(error);
});
關於 AbortController
官方實例
var controller = new AbortController();
var signal = controller.signal;
var downloadBtn = document.querySelector('.download');
var abortBtn = document.querySelector('.abort');
downloadBtn.addEventListener('click', fetchVideo);
abortBtn.addEventListener('click', function() {
controller.abort();
console.log('Download aborted');
});
function fetchVideo() {
...
fetch(url, {signal}).then(function(response) {
...
}).catch(function(e) {
reports.textContent = 'Download error: ' + e.message;
})
}