我正在实现一个函数timeout
,该函数将一个Promise转换为一个Promise,如果未在最短时间内解决该Promise,该Promise将被拒绝。
通过以下实现,uncaught (in promise)
当timeout
在分配的时间之前将promise传递给rejects时,我会在Chrome devtools中收到一条消息。
function timeout(promise, duration, message) {
const timeoutPromise = new Promise((_, reject) => {
const handle = setTimeout(() => {
reject(new TimeoutError(message ?? "Operation timed out."))
}, duration)
promise.finally(() => clearTimeout(handle)) //problem line
})
return Promise.race([promise, timeoutPromise])
}
但是,如果将其更改为以下内容,则似乎没有问题。
function timeout(promise, duration, message) {
const timeoutPromise = new Promise((_, reject) => {
const handle = setTimeout(() => {
reject(new TimeoutError(message ?? "Operation timed out."))
}, duration)
const clear = () => clearTimeout(handle)
promise.then(clear).catch(clear)
})
return Promise.race([promise, timeoutPromise])
}
我试图了解在第二种情况下调用then
&与catch
在第一种情况下调用有何不同finally
。
这是因为finally
处理程序不同于then
和catch
处理程序。如果承诺被拒绝,则finally
处理程序无法将拒绝更改为解决方案。像finally
一个的块try
/ catch
/finally
结构,它的意思是基本上透明的。
这是我在新书中描述的方式(第8章):
在正常情况下,
finally
处理程序对通过它的实现或拒绝没有影响(就像一个finally
块):它返回的任何值(除了被拒绝的thenable之外)都将被忽略。但是,如果它抛出错误或返回拒绝的罐头,则该错误/拒绝会取代通过它的任何实现或拒绝(就像在finally
块中抛出一样)。因此,它不能更改实现值-即使返回一个不同的值也是如此-但可以将拒绝原因更改为不同的拒绝原因,可以将实现更改为拒绝,并且可以延迟实现(通过返回最终实现的目标。或换一种说法:它就像一个
finally
不能包含return
语句的块。(它可能具有throw
或可能会调用一个函数或执行一些引发操作的操作,但是它不能返回新值。
这是一个无法将拒绝转化为实现的示例:
Promise.reject(new Error("Failed"))
.finally(() => {
console.log("finally handler returns null");
return null;
});
Look in the browser's real console to see the unhandled rejection error.
在您的代码中处理它的另一种方法是代替问题行执行此操作:
promise.catch(() => {}).finally(() => clearTimeout(handle))
要么
promise.catch(() => {}).then(() => clearTimeout(handle))
它将finally
(或then
)处理程序之前的拒绝转换为实现(仅在此分支上)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句