实现此目的的一种方法是将this.query(term) 承诺传递给一个函数,该函数将仅在查询花费的时间超过指定时间量(使用超时)时处理触发toggleWaiting。
例如,下面接受一个承诺,一个函数 (waitingFn) 将使用isWaiting 状态调用以及一个timeout,您可以使用它来指定您希望在您之前等待多长时间显示加载微调器。最后,当 Promise 实现时,我们返回结果:
async function handleWaiting(promise, waitingFn, timeout) {
let loadingStarted = false;
let timeoutInstance = null;
const timeoutPromise = new Promise((res) => {
timeoutInstance = setTimeout(() => {
loadingStarted = true;
waitingFn(true);
}, timeout);
return res();
});
function onFinished() {
clearTimeout(timeoutInstance);
if (loadingStarted) {
waitingFn(false);
}
}
try {
const [result] = await Promise.all([promise, timeoutPromise]);
onFinished();
return result;
} catch (ex) {
onFinished();
throw ex;
}
}
你可以像这样调用handleWaiting函数:
const result = await handleWaiting(this.query(term), (isWaiting) => this.toggleWaiting(), 500);
正如@FZs 和@Bergi 所指出的(谢谢你们),由于使用了promise 构造函数,下面是一个反模式:
function handleWaiting(promise, waitingFn, timeout) {
return new Promise((res, rej) => {
let loadingStarted = false;
const timeoutInstance = setTimeout(() => {
loadingStarted = true;
waitingFn(true);
}, timeout);
function onFinished() {
if (loadingStarted) {
waitingFn(false);
}
clearTimeout(timeoutInstance);
}
return promise
.then((result) => {
onFinished();
res(result);
})
.catch((ex) => {
onFinished();
rej(ex);
});
});
}