JavaScript取消Promise操作的常見實現方式
前言
在 JavaScript 中,Promise 本身沒有內置的取消機制,但我們可以通過一些模式來實現類似取消的功能。以下是幾種常見的實現方式
方法一:使用 Promise.race() 模擬取消
Promise.race 靜態(tài)方法接受一個 promise 可迭代對象作為輸入,并返回一個 Promise。這個返回的 promise 會隨著第一個 promise 的敲定而敲定。 那么我們可以傳給它兩個Promise,一個正常執(zhí)行,一個我們將Promise的reject方法緩存下來,只需要在我們需要取消的時候調用即可
// 封裝取消函數
const cancelPromise = (promise) => {
let cancel
// 定義一個取消的Promise
const rejectPromise = new Promise((_, reject) => {
cancel = () => {
reject({ name: 'cancel' })
}
})
const resultPromise = Promise.race([promise, rejectPromise])
return {
cancel,
promise: resultPromise
}
}
const { cancel, promise } = cancelPromise(
new Promise((resolve) => {
// 3s之后完成
setTimeout(() => {
resolve({ data: [] })
}, 3000)
})
)
promise
.then((res) => {
console.log('Promise Resolve', res)
})
.catch((error) => {
// 'cancel'
console.log(error.name)
})
setTimeout(() => {
cancel()
}, 2000)
方法二:使用 AbortController(推薦)
AbortController 是一個構造函數,其signal我們可以傳給fetch Api,然后我們只需要調用abort方法就可以取消該請求axios也支持該方法取消。
const controller = new AbortController()
fetch('http://api.com/query', { signal: controller.signal })
.then((res) => {
console.log(res)
})
.catch((error) => {
if (error.name === 'AbortError') {
console.log('Promise 已取消')
}
})
// 超時取消
setTimeout(() => {
controller.abort()
}, 2000)
被取消的請求會被瀏覽器標記為canceled

方法三:使用 Bluebird 庫
Bluebird 是一個完善的Promise庫,其完全遵循Promises/A+標準,所以我們可以像日常使用Promise一樣使用他,而且它有許多超越原生Promise的功能、比如支持 Promise 取消、進度追蹤、超時控制、更強大的錯誤處理機制(如 OperationalError)等。我們使用時候只需要安裝后直接引入即可
yarn add bluebird
import Promise from 'bluebird'
...
// 打開取消功能
Promise.config({ cancellation: true })
const testPromise = new Promise((resolve, reject, onCancel) => {
setTimeout(() => {
resolve('成功')
}, 3000)
onCancel(function () {
console.log('promise 已被取消')
})
})
.then((res) => {
console.log(res)
}).finally(() => {
// 判斷Promise是否取消
if(testPromise.isCancelled()) {
console.log('promise 已被取消')
}
})
setTimeout(() => {
// 取消Promise
testPromise.cancel()
}, 1000)
可以看到正常使用和原生Promise并無區(qū)別,但是新增了onCancel、cancel、config等Api,簡單介紹下
- cancel:用于取消當前Promise
- onCancel:Promise取消后會調用傳入該方法的回調
- isCancelled:判斷Promise是否取消
- config:配置項,因為取消Promise在當前版本中是默認關閉、傳入cancellation: true打開取消功能
總結與對比
在前端開發(fā)中,取消 Promise 操作是處理異步流程控制的重要能力。以下是各方案的對比:
方案對比
| 方案 | 優(yōu)點 | 缺點 | 適用場景 |
|---|---|---|---|
| Promise.race() | 純 JavaScript 實現,無需額外庫 | 只是"模擬"取消,實際異步操作仍在執(zhí)行 | 簡單的取消需求,兼容性要求高 |
| AbortController | 原生支持,與 fetch API 深度集成 | 較新的 API,需要 polyfill | 網絡請求取消,現代瀏覽器項目 |
| Bluebird | 功能豐富,API 完善 | 需要引入第三方庫,增加包體積 | 需要高級 Promise 功能的復雜應用 |
實踐建議
- 現代項目首選 AbortController - 隨著原生支持的普及,這是最標準和推薦的方式
- 簡單場景用 Promise.race() - 對于簡單的取消需求,這種方式足夠且輕量
- 復雜異步流程考慮 Bluebird - 如果需要進度追蹤、超時控制等高級功能
注意事項
- 取消 Promise 并不意味著底層操作真的停止了(如定時器)
- 要及時清理資源,避免內存泄漏
- 在 React/Vue 等框架中,組件卸載時務必取消未完成的異步操作
選擇合適的方法取決于具體需求、瀏覽器兼容性要求和項目架構。
以上就是JavaScript取消Promise操作的常見實現方式的詳細內容,更多關于JavaScript取消Promise操作的資料請關注腳本之家其它相關文章!
相關文章
微信小程序非swiper組件實現的自定義偽3D輪播圖效果示例
這篇文章主要介紹了微信小程序非swiper組件實現的自定義偽3D輪播圖效果,涉及微信小程序事件響應及元素屬性動態(tài)操作實現輪播圖效果相關技巧與注意事項,需要的朋友可以參考下2018-12-12
使用JavaScript實現網頁版Pongo設計思路及源代碼分享
Pongo是款很好玩的手欠類游戲,由于在玩的過程中發(fā)現了一些BUG,所以就打算自己也弄個,經過一番思索,就有了本文,主要說說實現這款游戲的設計思路以及分享源碼給大家2014-06-06
document.compatMode的CSS1compat使用介紹
這篇文章主要介紹了document.compatMode的CSS1compat使用,需要的朋友可以參考下2014-04-04

