5

Per alcuni metodi Typescript che costruisco, spesso ho bisogno dell'asincronicità di una promessa ma non ho bisogno della promessa di restituire un valore (concettualmente parlando). Un semplice esempio potrebbe essere chiamare un metodo initLanguageStrings() per caricare le stringhe della lingua utilizzate da un'applicazione. Le stringhe della lingua vengono inserite in una struttura globale, ma la promessa è ancora necessaria per garantire che l'applicazione non continui fino a quando non vengono caricate le stringhe della lingua.Come modificare il tipo di risultato di una Promessa < > in TypeScript

Più questo scenario due o tre volte e poi lego tutto il lavoro di inizializzazione in un insieme di promesse che collettivamente devono essere completate prima di continuare. Pertanto uso Promise.all, in questo modo (esempio):

initialiseApp(): Promise<void> 
{ 
    let promises: Promise<any>[ ] = [ ]; 

    promises.push(this.initLanguageStrings()); 
    promises.push(this.initModelData()); 
    promises.push(this.initUserInfo()); 

    return Promise.all(promises); 
} 

Il codice di cui sopra non sarà effettivamente compilazione (TS1.5/1,6) perché Promise.all() restituisce promessa < qualsiasi []> non promette < vuoto>.

Quindi quello che finiscono per scrivere è questo:

return new Promise((resolve, reject) => { 
    Promise.all(promises) 
     .then((dummy: any[ ]) => { 
     resolve(); 
     });   
}); 

Credo che questo sia semanticamente l'approccio corretto, perché la "realizzazione" rimane in realtà nascosta, e la "promessa interiore" (da Promise.all) mai "fughe" al chiamante di initialiseApp().

Ma d'altra parte trovo questo approccio brutto, e vorrei trovare un modo migliore per farlo, dal momento che restituire Promessa < vuoto diventa un modello abbastanza comune per me.

C'è un modo migliore per ottenere ciò che sto cercando di fare?

Il compilatore permetterà:

return Promise.all(promises).then(() => { }); 

Ma anche questo mi colpisce come "difficile" e brutto.

risposta

3

da quando è tornato Promessa < vuoto> sta diventando un bel modello comune per me

È possibile utilizzare un tipo di affermazione

initialiseApp(): Promise<void> 
{ 
    let promises: Promise<any>[ ] = [ ]; 

    promises.push(this.initLanguageStrings()); 
    promises.push(this.initModelData()); 
    promises.push(this.initUserInfo()); 

    return Promise.all(promises) as Promise<void>; 
} 

Nota: quando si utilizza un'affermazione si è essenzialmente in questo caso il sdraiato sul compilatore. Fai attenzione ai bug in cui il compilatore pensa una cosa e il runtime ne vede un'altra.

return Promise.all(promises).then(() => { });

questa è la strada giusta per farlo. Il tempo di esecuzione corrisponde a ciò che il compilatore ha dedotto. Se vuoi un Promise<void> ... quindi crea un Promise<void> che è ciò che fa questo esempio di codice.

+0

Lo svantaggio che vedo usando un cast (tipo assertion) è che non solo stiamo mentendo al compilatore, ma il risultato "dissanguato" dalla funzione al chiamante. In altre parole, il chiamante di initialiseApp riceverà infatti qualsiasi [] da Promise.tutto, anche se il metodo dice che nulla deve essere restituito. – Kevmeister68

Problemi correlati