typescript - TSLint - Löften måste hanteras korrekt med `finally`


Jag får detta fel från TSLint och jag försöker förstå varför det klagar.

Jag har en funktion som anropar en annan metod som returnerar ett löfte, men den första funktionen returnerar inte löftet eftersom den bara väntar på att det ska slutföras och uppdatera ett internt tillstånd.

Jag har förenklat det till denna funktion och använder bara Q() för att simulera ett anrop som returnerar ett löfte.

export function DoSomethingAsync(): void {
    Q().then(r => {
        console.log('test');
    }).catch(err => {
        log.error("wow");
    }).finally(() => {
        log.info("at finally")
    });
}

När jag kör tslint på mitt projekt nu får jag följande fel:

FEL: C:/dev/local_cache_service.ts[31, 5]: Löften måste hanteras på lämpligt sätt

Om jag tar bort finally-anropet passerar tslint utan fel.

export function DoSomethingAsync(): void {
    Q().then(r => {
        console.log('test');
    }).catch(err => {
        log.error("wow");
    });
}

När jag skapar samma funktion i ett grundläggande TypeScript-projekt uppstår inte detta beteende...

Svar #1

Detta är ett klagomål från regeln om inga svävande löften. Enligt dess beskrivning:

Att skapa ett löfte och inte lagra eller returnera det kan låta annan kod köras oberoende av dess resultat. Detta kan orsaka oväntat och/eller icke-deterministiskt beteende beroende på externa tidsfaktorer.

Det är vanligtvis bättre att returnera Promises från funktioner som startar dem och sedan hantera dem i den anropande koden.

Använd no-unused-expression utöver denna regel för att avslöja ännu fler flytande löften.

Specifikt i ditt fall är det för att du kör kod i ett .finally-block efter .catch-blocket. Detta anses vara farligt enligt regeln eftersom om koden inom .finally kastar ett fel, kommer det inte hanteras av den anropande koden.

Det bästa du kan göra är att returnera löftet, så att funktionens returtyp blir en Promise/Q istället för void.

Tips: du kan köra tslint -t stylish eller tslint -t verbose för att se regelnamn tillsammans med deras klagomål!

Svar #2

Lösningen var att lägga till ett anrop till .done() i slutet av kedjan av anrop på löftet.

Från vad jag förstod konverterar done alla obehandlade undantag till ett vanligt obehandlat undantag.

Relaterade artiklar