我有這樣的功能:
async howLongToMyBirthdayDate(date) {
return await new Promise((resolve, reject) => {
let bday;
if (!(date instanceof Date)) {
if (Number.isInteger(date) && date > 0) {
bday = new Date(date);
} else {
setTimeout(() => reject(new Error('Wrong argument!')), 1000);
return;
}
} else {
bday = date;
}
const today = new Date();
today.setHours(0, 0, 0, 0);
bday.setFullYear(today.getFullYear());
bday.setHours(0, 0, 0, 0);
if (bday - today === 0) {
setTimeout(() => resolve(this.congratulateWithBirthday()), 1000);
}
setTimeout(
() =>
resolve(this.notifyWaitingTime(Math.ceil((bday - today) / 86400000))),
1000
);
});
}
承諾解決了兩次。我看到函式 congratulateWithBirthday 和 notifyWaitingTime 的結果。正常嗎?我認為承諾只能解決或拒絕一次 - 通過第一次呼叫解決或拒絕回呼。也許 setTimeout 會改變它的行為?誰能給我解釋一下好嗎?
uj5u.com熱心網友回復:
您的承諾不需要解決兩次即可獲得您所描述的行為。您直接呼叫這兩個函式,因此當然會呼叫它們。第二個呼叫是否resolve執行任何操作都沒有關系。
這條線
resolve(this.notifyWaitingTime(Math.ceil((bday - today) / 86400000))),
沒有說“決議然后運行這個函式”,它說“呼叫這個函式,然后用它的回傳值呼叫resolve”。
撰寫此代碼的更合適的方法可能是這樣的:
async howLongToMyBirthdayDate(date) {
const result = await new Promise((resolve, reject) => {
let bday;
if (!(date instanceof Date)) {
if (Number.isInteger(date) && date > 0) {
bday = new Date(date);
} else {
setTimeout(() => reject(new Error('Wrong argument!')), 1000);
return;
}
} else {
bday = date;
}
const today = new Date();
today.setHours(0, 0, 0, 0);
bday.setFullYear(today.getFullYear());
bday.setHours(0, 0, 0, 0);
// resolve with how long until bday
if (bday - today === 0) {
setTimeout(() => resolve(0), 1000);
}
// we just resolve with how long until bday
setTimeout(
() =>
resolve(Math.ceil((bday - today) / 86400000)),
1000
);
});
if (result === 0) { this.congratulateWithBirthday(); }
else if (result > 0) { this.notifyWaitingTime(result); }
}
不是 100% 確定這解決了您的問題,因為我看不到您正在呼叫的函式是做什么的,但是我從您(ab)使用resolve方式的猜測是,您希望在計算后基本上呼叫兩個函式之一,具體取決于是否生日是現在與否。
uj5u.com熱心網友回復:
簡短的回答,是的,鑒于您的代碼它將解決兩次。原因是因為congratulateWithBirthday和notifyWaitingTime不以彼此為條件,因此它們將在同一運行中被呼叫。
如果你想避免這種情況,你應該有類似的東西
if (bday - today === 0) {
setTimeout(() => resolve(this.congratulateWithBirthday()), 1000);
} else {
setTimeout(() => resolve(this.notifyWaitingTime(Math.ceil((bday - today) / 86400000))), 1000);
}
另外,作為旁注,請嘗試在使用async/await或之間做出決定Promise。沒有理由同時使用兩者,它使代碼看起來很奇怪。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/388359.html
標籤:javascript 异步 承诺
上一篇:JavaScript:異步錯誤處理與async/await和then/catch之間的區別
下一篇:如何對元素XSL進行兩次轉換
