[英]await/async how to handle unresolved promises
你如何處理沒有解決的承諾?
例子:
class Utils {
static async thisFunctionOnlyResolvesWhenPassed2AndNeverRejects(number: number) {
return new Promise((resolve, reject) => {
if(number === 2) {
resolve('ok')
}
})
}
}
console.log(await Utils.thisFunctionOnlyResolvesWhenPassed2AndNeverRejects(2))
// this will print "ok" because 2 is passed and the promise is resolved
console.log(await Utils.thisFunctionOnlyResolvesWhenPassed2AndNeverRejects(5))
// this will crash the program silently
uncaughtException
和unhandledRejection
當承諾未解決時不返回任何內容。 在等待周圍添加try/catch
不起作用(沒有錯誤)。 最后,唯一有效的是使用Promise.then
而不是await
。
問題是代碼庫充斥着async/await
和有時會解決的承諾(取決於條件)
問題:是否可以添加打字稿標志來檢測丟失的解析/拒絕? 或者也許是一種將所有async/await
Promise.then
為使用Promise.then
的自動化方式?
使用調試器時,程序在 Promise 之后停止,很難找到哪個函數/promise 丟失了 resolve/reject。
重寫所有async/await
調用以使用Promise.then
是我最后的手段。
如果您的承諾偶爾無法解決或拒絕,並且這不是他們應該工作的方式(通常不是),那么您只需要解決這個問題。 真的沒有解決方法。 正確的解決方法是深入到最低級別並修復代碼,以便它每次都能可靠地解決或拒絕。
這不是正確的修復,但實現超時包裝器可以幫助調試,為您提供一條日志消息,其中包含一些類似於超時承諾的堆棧跟蹤:
function rejectT(t) {
// create potential error here for better opportunity at stack trace
let e = new Error("Promise timed out");
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(e);
reject(e);
}, t);
});
}
function timeout(p, t = 5000) {
return Promise.race([p, rejectT(t)]);
}
然后,您可以包裝任何承諾,而不是:
fn().then(...).catch(...)
您可以使用:
timeout(fn()).then(...).catch(...);
或者,如果您想設置自定義超時值:
timeout(fn(), 1000).then(...).catch(...);
同樣,這是調試代碼以幫助找到需要修復的罪魁禍首並幫助測試修復,而不是捆綁您的代碼。
重寫所有 async/await 調用以使用 Promise.then 是我最后的手段。
我根本看不出這會有什么幫助。 如果await
永遠不會完成,則promise.then()
也不會完成。 他們在這方面完全相同。 如果承諾永遠不會解決或拒絕,那么.then()
處理程序也永遠不會被調用。
問題是代碼庫充斥着 async/await 和有時會解決的承諾(取決於條件)
除了有條不紊的代碼審查之外,這里沒有其他捷徑,可以找到具有永遠無法解析或拒絕的代碼路徑的可疑代碼,然后構建單元測試來測試在各種條件下返回承諾的每個函數。
一種可能永遠不會解析或拒絕的代碼來源是一些 promise 反模式。 其中一些是反模式的確切原因是因為它們很容易搞砸。 以下是一些可能會激發您對可疑代碼的敏感性的參考資料:
async function thisFunctionOnlyResolvesWhenPassed2AndNeverRejects(number) { return new Promise((resolve, reject) => { if (number === 2) { resolve('ok') } else { reject('error:' + number) } }) } (async() => { try { console.log(await thisFunctionOnlyResolvesWhenPassed2AndNeverRejects(2)) // this will print "ok" because 2 is passed and the promise is resolved } catch (e) { console.error(e); } try { console.log(await thisFunctionOnlyResolvesWhenPassed2AndNeverRejects(5)) // this will crash the program silently } catch (e) { console.error(e); } })()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.