此功能用于等待毫秒数。
function delay(millis: number) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, millis);
});
然后我的目标是使此函数超时吗?
const timeout = await delay(20000);
在其他地方单击时,用户无聊的等待中
clearTimeout(timeout)
答案 0 :(得分:2)
只需扩展您将发送的Promise对象:
function delay( millis ) {
let timeout_id;
let rejector;
const prom = new Promise((resolve, reject) => {
rejector = reject;
setTimeout(() => {
resolve();
}, millis);
});
prom.abort = () => {
clearTimeout( timeout_id );
rejector( 'aborted' );
};
return prom;
}
const will_abort = delay( 2000 );
const will_not_abort = delay( 2000 );
will_abort
.then( () => console.log( 'will_abort ended' ) )
.catch( console.error );
will_not_abort
.then( () => console.log( 'will_not_abort ended' ) )
.catch( console.error );
setTimeout( () => will_abort.abort(), 1000 );
答案 1 :(得分:1)
您可以返回解决/拒绝以及承诺
function delay(millis) {
let reolver;
return [new Promise((resolve, reject) => {
resolver = resolve
x = setTimeout(() => {
resolve();
}, millis);
}), resolver];
}
const [sleep1, wake1] = delay(2000)
sleep1.then((x) => console.log(x || 'wakeup 1')) // Auto wake after 2 seconds
const [sleep2, wake2] = delay(2000)
sleep2.then((x) => console.log(x || 'wakeup 2'))
wake2('Custom Wakeup') // sleep2 cancelled will wake from wake2 call
答案 2 :(得分:0)
您可以返回一个函数,该函数从cancelTimer
函数调用中以数组的形式取消计时器(Promise
和delay
对象。
然后根据需要使用cancelTimer
清除它,这也会拒绝Promise
:
function delay(millis) {
let cancelTimer;
const promise = new Promise((resolve, reject) => {
const timeoutID = setTimeout(() => {
resolve("done");
}, millis);
cancelTimer = () => {
clearTimeout(timeoutID);
reject("Promise cancelled");
};
});
return [promise, cancelTimer];
}
//DEMO
let [promiseCancelled, cancelTimer] = delay(20000);
(async() => {
try {
console.log("Promise result never printed", await promiseCancelled);
} catch (error) {
console.error("Promise is rejected", error);
}
})();
cancelTimer();
const [promise, _] = delay(2000);
(async() => {
console.log("Promise result printed", await promise);
})();
答案 3 :(得分:0)
我建议您不要通过在其上附加.abort
方法来修改诺言。而是从您的延迟函数中返回两个值
重要的是,我们看不到"x"
已登录到控制台,因为它已被取消-
function useDelay (x = null, ms = 1000)
{ let t
return [
new Promise(r => t = setTimeout(r, ms, x)), // 1
_ => clearTimeout(t) // 2
]
}
const [x, abortX] =
useDelay("x", 5000)
const [y, abortY] =
useDelay("y canceled x", 2000)
x.then(console.log, console.error)
y.then(console.log, console.error).finally(_ => abortX())
console.log("loading...")
// loading...
// y canceled x
交互式演示
这是一个交互式示例,允许您等待延迟值或中止它-
function useDelay (x = null, ms = 1000)
{ let t
return [
new Promise(r => t = setTimeout(r, ms, x)), // 1
_ => clearTimeout(t) // 2
]
}
const [ input, output ] =
document.querySelectorAll("input")
const [go, abort] =
document.querySelectorAll("button")
let loading = false
function reset ()
{ loading = false
input.value = ""
go.disabled = false
abort.disabled = true
}
function load ()
{ loading = true
go.disabled = true
abort.disabled = false
}
go.onclick = e => {
if (loading) return
load()
const [delayedValue, abortValue] =
useDelay(input.value, 3000)
abort.onclick = _ => {
abortValue()
reset()
}
delayedValue
.then(v => output.value = v)
.catch(e => output.value = e.message)
.finally(_ => reset())
}
code { color: dodgerblue; }
<input placeholder="enter a value..." />
<button>GO</button>
<button disabled>ABORT</button>
<input disabled placeholder="waiting for output..." />
<p>Click <code>GO</code> and the value will be transferred to the output in 5 seconds.</p>
<p>If you click <code>ABORT</code> the transfer will be canceled.</p>