如何将Promise.all()与Typescript一起使用
以下是我想做的:如何将Promise.all()与Typescript一起使用,typescript,Typescript,以下是我想做的: Promise.all([aurelia.start(), entityManagerProvider.initialize()]) .then((results:Array<any>) => { let aurelia: any = results[0]; aurelia.setRoot(); }); Promise.all([aurelia.start(),entityManagerProvider.ini
Promise.all([aurelia.start(), entityManagerProvider.initialize()])
.then((results:Array<any>) => {
let aurelia: any = results[0];
aurelia.setRoot();
});
Promise.all([aurelia.start(),entityManagerProvider.initialize()]))
.然后((结果:数组)=>{
设aurelia:any=结果[0];
毛状根();
});
aurelia.start()
返回aurelia类型,而initialize()
返回void
编译器给出一条错误消息,表示无法从用法推断类型
我试图实现的是让它们同时运行,因为它们都是非常长的进程,然后运行
Aurelia.setRoot()代码>这是TypeScript及其承诺中的一个弱点。所有签名。通常,最好使用类型一致的数组。您可以手动执行以下操作:
let foo : [Promise<Aurelia>,Promise<void>] = [aurelia.start(), entityManagerProvider.initialize()];
Promise.all(foo).then((results:any[]) => {
let aurelia: any = results[0];
aurelia.setRoot();
});
让foo:[Promise,Promise]=[aurelia.start(),entityManagerProvider.initialize()];
Promise.all(foo).then((结果:any[])=>{
设aurelia:any=结果[0];
毛状根();
});
由于Promise::all
是一个通用函数,因此可以像下面这样声明每个Promise的返回类型:
Promise.all<Aurelia, void>([
aurelia.start(),
entityManagerProvider.initialize()
])
.then(([aurelia]) => aurelia.setRoot());
Promise.all([fooPromise, barPromise]).then(([foo, bar]) => {
// compiler correctly warns if someField not found from foo's type
console.log(foo.someField);
});
Promise.all([
aurelia.start(),
entityManagerProvider.initialize()
])
.然后(([aurelia])=>aurelia.setRoot());
如果希望保持类型安全,可以扩展Promise
对象(类型为PromiseConstructor
)的本机类型定义,并为whenPromiseConstructor
)添加额外的重载签名。调用所有时,不一定使用可相互分配的有限值:
interface PromiseConstructor
{
all<T1, T2>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>]): Promise<[T1, T2]>;
all<T1, T2, T3>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>]): Promise<[T1, T2, T3]>;
...
}
至少从TypeScript2.7.1
开始,编译器似乎在没有帮助的情况下解析类型,语法如下:
Promise.all<Aurelia, void>([
aurelia.start(),
entityManagerProvider.initialize()
])
.then(([aurelia]) => aurelia.setRoot());
Promise.all([fooPromise, barPromise]).then(([foo, bar]) => {
// compiler correctly warns if someField not found from foo's type
console.log(foo.someField);
});
帽子提示:@JamieBirch(从评论到@AndrewKirkegaard的回答)我在寻找Promise.all()
的返回类型时不知何故来到这里,因为直截了当的[Promise,Promise]
显然不起作用
最终,事情变得比看上去更简单:
const severalMongoDbOperations: Promise<[DeleteWriteOpResultObject, UpdateWriteOpResult]> =
() => Promise.all([
mongo.deleteOne({ ... }),
mongo.updateOne({ ... })
]);
我和你有同样的问题,但是有了这个代码,所有的工作都很完美
type TList = Promise<Aurelia> | Promise<void>;
const foo: TList[] = [aurelia.start(), entityManagerProvider.initialize()];
Promise.all<TList>(foo).then((results) => {
let aurelia = results[0];
aurelia.setRoot();
});
type TList=Promise | Promise;
const-foo:TList[]=[aurelia.start(),entityManagerProvider.initialize()];
Promise.all(foo).然后((结果)=>{
设aurelia=results[0];
毛状根();
});
我最喜欢使用的Promise.all()
当使用promises时,返回值使用数组重组,如下所示。使用wait
更具可读性,而解构则是填充正确的变量
export interface IDeveVersionHubDataService {
getBuildFilterDeveVersions(): Promise<IBuildFilterDeveVersionDto[]>;
getBuildFilterUsers(): Promise<IBuildFilterUserDto[]>;
}
第一部分
有一些函数需要理解A)承诺。所有
和B)承诺。然后
:
A) Promise.all的类型定义是一个函数:
all<T>(values: readonly (T | PromiseLike<T>)[]): Promise<T[]>;
第一部分a
Promise。那么
的类型定义很多,但可以分解为几个小部分:
then
a函数then
带有两个泛型TResult1、TResult2
。
意味着我们以后可以在它们内部设置和使用值-它们被调用
然后
函数本身:(oncompleted?:…,onrejected?:…):Promise
PromiseLike
是一种助手类型,与Promise
相同(用于介绍课程)
onfulfilled
和onrejected
是以下形式的函数:(值:T)=>(TResult1或PromiseLike)
或未定义
或空
。请注意这里使用的是泛型T
第二部分-
Promise本身有一个通用接口:接口Promise
。
是一个/
所以当你打电话的时候
Promise.all<SomeCoolType>([a(), b(), c()]).then( value => doSomething(value) )
Promise.all([a(),b(),c()])。然后(value=>doSomething(value))
您的泛型是SomeCoolType
,在本例中,某个cool类型是
interface SomeCoolType=[A()=>string,B()=>boolean,C()=>number]
现在请记住,abc
必须是承诺。这使得它成为中的值。然后(value=>…
将进入SomeCoolType
的结果,我们调用所有这些函数,结果是[字符串,布尔值,数字]
结论-
具体地说,您传递给您的函数/承诺数组Promise。所有都是中使用的泛型。然后(result=>…)
。这些承诺的返回/解析值将成为result
的值/类型
示例:Promise.all]>([returnStringAsync()])。然后(result=>console.log(typeof result==“string”);#=>true
Visual Studio代码批准该语法,但绑定在生成系统中的tslint
会抱怨:数组未正确声明,它应该是类型[]或者数组。奇怪的是,搜索该错误消息只会产生0个结果。所以写让foo:Array=[aurelia.start(),entityManagerProvider.initialize()]
现在看来,这对我来说是纯推理。它返回一种非常有效的承诺类型。我不确定这是由于最近的编译器功能,还是只是ES6承诺的键入现在比以前更好。无论如何,这里的推断令人印象深刻。-1:通过承诺键入。所有
都比以前更好raightforward比首先声明承诺的类型化数组要好。请看答案:在vscode中,它工作得很好。但是,当我通过tsc编译它时,它会说错误TS2346:提供的参数与调用目标的任何签名都不匹配。
(tsc-v 2.0.6)。有什么解决方案吗?这会产生“提供的参数与调用目标的任何签名都不匹配。”在2.1.4中也是如此。在Typescript2.7.2
中,我发现它能够正确推断传递到then()中的数组中的类型Promise::all
@JamieBirch谢谢,它似乎也适用于2.7.1
。我认为这是一个
then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<TResult1 | TResult2>;
Promise.all<SomeCoolType>([a(), b(), c()]).then( value => doSomething(value) )