2015-10-06 106 views
5

對於我構建的一些Typescript方法,通常需要承諾的異步性,但我不需要承諾返回值(概念上講)。一個簡單的例子可能是調用initLanguageStrings()方法來加載應用程序使用的語言字符串。語言字符串被放置到全局結構中,但承諾仍然是必要的,以確保在加載語言字符串之前應用程序不會繼續。如何在TypeScript中更改Promise < >的結果類型

將此場景重複兩次或三次,然後將所有初始化工作綁定到一組承諾中,這些承諾必須在繼續之前全部完成。因此,我使用Promise.all,像這樣(舉例):

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

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

    return Promise.all(promises); 
} 

上面的代碼將不實際編譯(TS1.5/1.6),因爲Promise.all()返回無極<任何[]>不能保證< void>。

所以我寫出來是這樣的:

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

我相信這是語義正確的做法,因爲「執行」實際上保持隱藏,而「內的承諾」(從Promise.all)從不「逃避」initialiseApp()的調用者。

但另一方面,我覺得這種方法很醜,並希望找到一個更好的方法來做到這一點,因爲返回Promise < void>正在成爲我的一個常見模式。

有沒有更好的方法來實現我想要做的?

編譯器將允許:

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

但它也給我的印象是「刁鑽」的和醜陋。

回答

3

因爲返回無極<無效>正在成爲一個相當普遍的模式,我

您可以使用一個類型斷言

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>; 
} 

注意:當您使用斷言你本質上是在這種情況下向編譯器說謊。在編譯器認爲是一件事而運行時看到另一件事的時候,要小心一些錯誤。

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

這是正確辦法做到這一點。 運行時間匹配什麼編譯器已推斷。如果你想要一個Promise<void> ...那麼作出Promise<void>這就是這個代碼示例。

+0

我看到使用cast(type assertion)的缺點是,我們不僅向編譯器說謊,而且結果會將函數「調出」給調用者。換句話說,initialiseApp的調用者實際上會收到來自Promise的任何[]。儘管該方法表示什麼都不應該返回。 – Kevmeister68

相關問題