Способ добиться этого — передать обещание this.query(term)
функции, которая будет обрабатывать запуск toggleWaiting
только тогда, когда запрос занимает больше времени, чем указанное количество времени (используя тайм-аут).
Например, в приведенном ниже примере используется обещание, функция (waitingFn
), которая будет вызываться со статусом isWaiting
, а также timeout
, которую вы можете использовать, чтобы указать, как долго вы хотите ждать, прежде чем показывать счетчик загрузки. Наконец, когда обещание выполнено, мы возвращаем результат:
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 (спасибо вам обоим), ниже приведен антипаттерн из-за использования конструктора обещаний:
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);
});
});
}
person
ljbc1994
schedule
11.12.2020