簡體   English   中英

等待try / catch和嵌套promise

[英]await with try/catch and nested promises

也許有點愚蠢的問題,但是我應該在名為“ actionTwo()”的方法中兌現諾言嗎? 什么是最佳做法?

async actionOne(req, res, next) {
    try {
        await this.actionTwo();
    } catch( error ) => {
       // catch the error
    }
}

async actionTwo(req, res, next) {
    return new Promise( function( resolve, reject ) {
        // do something
        resolve()
    })
    .catch( error ) {
        // Do I need this catch statement???
        reject( error )
    }
}

在可以處理該錯誤的任何函數中捕獲該錯誤。 這可以是一個功能,也可以是兩個功能,或者兩者都不是。

在您的示例中,如果actionTwo每當遇到錯誤時actionTwo需要執行某些操作(例如,記錄該actionTwo失敗),那么您確實應該catch它的內部。 但是,如果actionTwo本身並不需要做任何事情,特別是當它遇到一個錯誤,不.catch里面,而是只返回被拒絕的承諾,以便其消費(在這里, actionOne )可以處理錯誤。

如果actionOne可以看到錯誤並做一些有用的事情(例如,記錄actionOne失敗,或呈現錯誤頁面等),則actionOne應該捕獲該錯誤。 否則,捕獲錯誤沒有太大用處,您應該只返回actionOne Promise(由async函數自動創建)供asyncOne的使用者處理。

最終,所有錯誤都應該被捕獲到某個地方 ,否則您將得到無法處理的拒絕。

請記住,如果被調用函數需要處理錯誤, 並且其使用者也需要查看和處理錯誤,則被調用函數將不得不在其catch重新拋出錯誤,例如:

async actionOne(req, res, next) {
    try {
        await this.actionTwo();
    } catch( error ) => {
       // catch the error
    }
}

async actionTwo(req, res, next) {
    return new Promise( function( resolve, reject ) {
        // do something
        resolve()
    })
    .catch( error ) {
        // handle error
        throw error;
    }
}

一般無, actionTwo不會趕上拒絕,它會轉嫁給他們的調用者(這反過來又可能將它們傳遞到它的調用者,等等)。

在不再具有async功能的頂層,通常會捕獲錯誤並以某種適當的方式報告錯誤。

顯然,該規則有例外(無雙關語)。 如果actionTwo可以有意義地將拒絕轉化為實現,那么是的,這樣做是有意義的。


請注意,問題中的actionTwo要么不應該async ,要么不應該使用new Promise ,這取決於“做什么”。

在下面的:

  • 我稱其為“做某事” doSomething();
  • 根據問題, actionOneactionTwo是對象文字或類定義中的方法,因此我將在下面使用該形式

如果doSomething()返回一個promise,那么在正常情況下actionTwo看起來像這樣:

actionTwo() { // No `async`
    return doSomething();
}

要么

async actionTwo() {
    const x = await doSomething();
    // ...do something with `x`...
    return x;
}

這種形式也可以:

async actionTwo() { // With `async`
    return doSomething();
}

...雖然不必要。 它曾經引入了一個額外的異步“ tick”(通常是無害的),但是最近在規范中得到了改進,我們可以預期JavaScript引擎很快就會采用這種更改。

如果doSomething是老式的回調樣式異步函數,則actionTwo通常如下所示:

actionTwo() {
    return new Promise((resolve, reject) {
        doSomething(function() {
            if (/*...the action failed...*/) {
                reject(new Error(/*...with failure information...*/));
            } else {
                resolve(/*...with the result...*/);
            }
        });
    });
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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