# 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)