# AbortController
# 取消 fetch() 請求
const controller = new AbortController();
const res = fetch('/', { signal: controller.signal });
controller.abort();
console.log(res); // Promise(rejected): "DOMException: The user aborted a request"
1
2
3
4
2
3
4
可以參考官方的 使用範例 (opens new window)。
# 取消非同步事件
這面的範例為取消 10 秒的暫停器:
function timeout(duration, signal) {
return new Promise((resolve, reject) => {
const handle = setTimeout(resolve, duration);
signal?.addEventListener('abort', (e) => {
clearTimeout(handle);
reject(new Error('aborted'));
});
});
}
const controller = new AbortController();
const promise = timeout(10000, controller.signal);
controller.abort();
console.log(promise); // Promise {<rejected>: Error: aborted
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
範例說明:
- 函式為回傳
promise時,在promise中的同步動作,會在 函式呼叫時先被執行 AbortController的signal有實做EventTarget介面,可以使用addEventListener方法timeout函式中偵聽abort事件,讓controller.abort()時清除暫存器
# 取代事件的偵聽
以往常使用的 removeEventListener 方法取消對目標物件的事件監聽,現在可以透過 abort() 達到一樣的效果。
const controller = new AbortController();
eventTarget.addEventListener('event-type', handler, {
signal: controller.signal,
});
controller.abort();
1
2
3
4
5
2
3
4
5
雖然在 Chrome 88 已可以使用 AbortController,但 addEventListener 的第三個參數設定 { signal: xxx } 還沒有支援,預計會在 Chrome 90 版本中啟用。可以先參考 event-target-shim (opens new window) 套件。
# 拖曳的實做
範例說明:
mousedown事件時,註冊window的mousemove和mouseup偵聽mousemove事件時,移動目標的位置mouseup事件時,透過abort()移除window對mousemove和mouseup的偵聽
# 參考
Using AbortController as an Alternative for Removing Event Listeners (opens new window)