2 回答

TA貢獻1772條經驗 獲得超5個贊
實現此目的的一種方法是將承諾傳遞給一個函數,該函數將僅在查詢花費的時間超過指定時間(使用超時)時this.query(term)處理觸發。toggleWaiting
例如,下面的代碼接受一個 Promise,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 所指出的(謝謝你們),下面是由于使用 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);
});
});
}

TA貢獻1820條經驗 獲得超10個贊
在我的 alpineJs 對象中 - 我有這個實現:
{
? ?waiting: false,
? ?async handleWaiting(promise, timeout) {
? ? ? ?return new Promise((res, rej) => {
? ? ? ? ? ?let loadingStarted = false;
? ? ? ? ? ?const timeoutInstance = setTimeout(() => {
? ? ? ? ? ? ? ?loadingStarted = true;
? ? ? ? ? ? ? ?this.waiting = true;
? ? ? ? ? ?}, timeout);
? ? ? ? ? ?const onFinished = () => {
? ? ? ? ? ? ? ?if (loadingStarted) {
? ? ? ? ? ? ? ? ? ?this.waiting = false;
? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ?clearTimeout(timeoutInstance);
? ? ? ? ? ?}
? ? ? ? ? ?promise
? ? ? ? ? ? ? ?.then((result) => {
? ? ? ? ? ? ? ? ? ?onFinished();
? ? ? ? ? ? ? ? ? ?res(result);
? ? ? ? ? ? ? ?})
? ? ? ? ? ? ? ?.catch((ex) => {
? ? ? ? ? ? ? ? ? ?onFinished();
? ? ? ? ? ? ? ? ? ?rej(ex);
? ? ? ? ? ? ? ?});
? ? ? ?});
? ? },
? ? async searchForTerm(term) {
? ? ? ?this.results = await this.handleWaiting(this.$wire.query(term), 500);
? ? ? ?// do something with the results...
? ? },
?}
非常簡單。
添加回答
舉報