Javascript ClearTimeout使用承诺内的最佳实践
我有一个关于clearTimeout方法的问题(对于noob的问题,我提前表示歉意)。我想知道在下面的代码中清除超时的最佳位置是哪里?我有一个“getResponse()”函数,它将被多次调用。我不确定在哪里放置clearTimeout的最佳位置,以便在responseTimeout解决或拒绝时立即清除超时。谢谢Javascript ClearTimeout使用承诺内的最佳实践,javascript,settimeout,cleartimeout,Javascript,Settimeout,Cleartimeout,我有一个关于clearTimeout方法的问题(对于noob的问题,我提前表示歉意)。我想知道在下面的代码中清除超时的最佳位置是哪里?我有一个“getResponse()”函数,它将被多次调用。我不确定在哪里放置clearTimeout的最佳位置,以便在responseTimeout解决或拒绝时立即清除超时。谢谢 function getResponse() { const responseTimeout = new Promise((resolve, reject) => {
function getResponse() {
const responseTimeout = new Promise((resolve, reject) => {
let id = setTimeout(() => {
if (!messageHandled) {
reject(`Timed out to get response`);
}
}, 3000);
});
const responsePromise = new Promise((resolve, reject) => {
// some code which returns response promise
});
return Promise.race([
responsePromise,
responseTimeout
]);
}
通常,我会在承诺本身中这样做,并避免两个单独承诺的开销
function getResponse(...params) {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error("Timed out to get response"))
// some code to abort request
}, 3000)
// some code which resolves promise
})
}
有益的是,承诺会在您第一次解决后忽略以后的解决方案和/或拒绝。如果您可以在不触发解析逻辑的情况下以编程方式中止它,这将变得更加容易,但是即使您不能,您也可以始终使用布尔值来阻止将来的请求。它还使以后添加取消支持变得更容易,这也很有帮助。如果您还需要关闭超时(如果您正在执行一些DOM变异或文件读取-您很少需要这样做),您可以执行以下操作:
function getResponse(...params) {
return new Promise((reallyResolve, reallyReject) => {
let resolved = false
let id = setTimeout(() => {
reject(new Error("Timed out to get response"))
abort()
}, 3000)
// I'll use these instead of the `resolve`/`reject` callbacks directly.
function resolve(value) {
if (resolved) return
resolved = true
clearTimeout(id)
reallyResolve(value)
}
function reject(value) {
if (resolved) return
resolved = true
clearTimeout(id)
reallyReject(value)
}
function abort() {
// some code to abort request
}
// some code which resolves promise
})
}
这使得我不必担心如何安排一切,但它仍然有效
如果您不需要中止逻辑(您只在网络请求和类似情况下需要中止逻辑),这将变得简单得多:
function timeout(ms) {
return new Promise((_, reject) => {
setTimeout(() => reject(new Error("Timed out")), ms)
})
}
function getResponse(...params) {
return Promise.race([
timeout(3000),
doSomethingAsync(),
])
}
在给定的代码中,您没有调用
clearTimeout
,您是否忘记添加它?但无论如何,你实际上根本不需要清除它。你的承诺。种族将只解决一次,由第一个承诺解决,并将忽略另一个。所以你现在拥有的应该很好。我没有忘记,我不知道放在哪里。在Promise.race中,当第一个需要更长的时间并且timeoutpromise拒绝时,我应该清除超时吗?getResponse函数将被调用多次,这就是我想要清除它的原因。如果我的想法不正确,请告诉我。更新问题使其更清晰。啊,我以为这个代码块是您提到的第一稿。就我个人而言,我不想澄清这一点,一个简单的承诺拒绝被默默忽略,而保留复杂的闭包只是为了能够取消这个非常小的时间,这并没有什么坏处。执行将产生更复杂的代码维护。但这是意见我不知道从GC的角度看,永远等待的承诺会发生什么。实际上,最好根本不清除超时。但是如果您确实想这样做,那么在getResponse
中初始化id
,并在responsePromise
中清除它@kaido Fixed。谢谢你的帮助。(我很少使用Promise.race
我有时几乎忘记了这一点。)