簡體   English   中英

等待/異步如何處理未解決的承諾

[英]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 

uncaughtExceptionunhandledRejection當承諾未解決時不返回任何內容。 在等待周圍添加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 反模式。 其中一些是反模式的確切原因是因為它們很容易搞砸。 以下是一些可能會激發您對可疑代碼的敏感性的參考資料:

Promise 反模式

常見的 Promise 反模式以及如何避免它們

ES6 Promises:模式和反模式

 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM