3 回答

TA貢獻1843條經驗 獲得超7個贊
Promise 本身是不可取消的,但在有限的意義上會通過導致它們被拒絕來取消。
考慮到這一點,可以通過少量的詳細說明Promise.race()和您希望取消的承諾返回功能來實現取消。
function makeCancellable(fn) {
var reject_; // cache for the latest `reject` executable
return function(...params) {
if(reject_) reject_(new Error('_cancelled_')); // If previous reject_ exists, cancel it.
// Note, this has an effect only if the previous race is still pending.
let canceller = new Promise((resolve, reject) => { // create canceller promise
reject_ = reject; // cache the canceller's `reject` executable
});
return Promise.race([canceller, fn.apply(null, params)]); // now race the promise of interest against the canceller
}
}
假設您的 http 調用函數已命名httpRequest(promise令人困惑):
const search = makeCancellable(httpRequest);
現在,每次search()調用時,都會調用緩存的reject可執行文件以“取消”前面的搜索(如果它存在并且其競爭尚未完成)。
// Search 1: straightforward - nothing to cancel - httpRequest(200) is called
search(200)
.then(function() { console.log('search1 resolved') })
.catch(function(err) { console.log('search3 rejected', err) });
// Search 2: search 1 is cancelled and its catch callback fires - httpRequest(2000) is called
search(2000)
.then(function() { console.log('search2 resolved') })
.catch(function(err) { console.log('search3 rejected', err) });
// Search 3: search 2 is cancelled and its catch callback fires - httpRequest(1000) is called
search(1000)
.then(function() { console.log('search3 resolved') })
.catch(function(err) { console.log('search3 rejected', err) });
如有必要,catch 回調可以進行測試err.message === '_cancelled_'以區分取消和其他拒絕原因。
添加回答
舉報