点击上方 前端Q,关注公众号
回复加群,加入前端Q技术交流群
在JavaScript中,Promise是用于处理异步操作的对象,它代表一个异步操作的最终完成(或失败)及其结果值。然而,JavaScript的Promise并不提供内置的取消(cancel)机制。
Promise是经过了深思熟虑,才不自带取消功能的!!!
这篇文章,将围绕着设计的哲学,以及从状态机的角度,解释为什么不需要cancel。
即使如此,文章最后部分,还是会提供一些方法,来实现一下cancle。
在输入一个状态时,只得到一个固定的状态。
一个Promise可以被看作是一个简单的状态机,它有以下几种状态:
状态转换规则如下:
引入取消功能意味着需要增加一个新的状态——“Cancelled(已取消)”。这会使状态机的设计变得更加复杂,因为需要考虑更多的状态转换和边界情况。
如果我们引入“Cancelled”状态,状态机的状态和转换规则将变成:
这种增加的复杂性会导致以下问题:
尽管标准的Promise没有内置的取消功能,可以通过一些方法来实现类似的功能。例如,使用AbortController来取消网络请求,或者使用自定义的Promise包装器来支持取消。
对于Fetch API,可以使用AbortController来取消请求:
const controller = new AbortController();
const signal = controller.signal;
fetch('https://www.baidu.com', { signal })
.then(response => response)
.then(data => console.log(data))
.catch(err => {
if (err.name === 'AbortError') {
console.log('Fetch aborted');
} else {
console.error('Fetch error:', err);
}
});
// 取消请求
controller.abort();
也可以创建一个支持取消的自定义Promise包装器:
class CancellablePromise {
constructor(executor) {
this._hasCanceled = false;
this._promise = new Promise((resolve, reject) => {
executor(
value => this._hasCanceled ? reject({ canceled: true }) : resolve(value),
reason => this._hasCanceled ? reject({ canceled: true }) : reject(reason)
);
});
}
cancel() {
this._hasCanceled = true;
}
then(onFulfilled, onRejected) {
return this._promise.then(onFulfilled, onRejected);
}
catch(onRejected) {
return this._promise.catch(onRejected);
}
}
// 使用自定义的CancellablePromise
const cancellablePromise = new CancellablePromise((resolve, reject) => {
setTimeout(() => resolve('Completed!'), 1000);
});
cancellablePromise.then(
result => console.log(result),
err => {
if (err.canceled) {
console.log('Promise was canceled');
} else {
console.error('Promise error:', err);
}
}
);
// 取消Promise
cancellablePromise.cancel();
虽然标准的Promise没有内置取消功能,但可以通过这些方法来实现取消逻辑,根据实际需求选择合适的方案。
虽然JavaScript的Promise没有内置取消功能,但这并不意味着我们无法实现取消功能。通过理解Promise的设计哲学和状态机模型,我们可以更好地掌握其使用方法,并通过巧妙的编程技巧实现我们需要的功能
本文转载于掘金-德玛西亚大宝剑之力
原文:https://juejin.cn/post/7373986431850872869
往期推荐
欢迎加我微信,拉你进技术群,长期交流学习...
欢迎关注「前端Q」,认真学前端,做个专业的技术人...