如何使用Typescript的Promise.All

Gre*_*Gum 40 typescript

这是我想要做的:

Promise.all([aurelia.start(), entityManagerProvider.initialize()])
    .then((results:Array<any>) => {
        let aurelia: any = results[0];
        aurelia.setRoot();
    });
Run Code Online (Sandbox Code Playgroud)

arelia.start()返回Aurelia类型,而initialize()返回void.

编译器会给出一条错误消息,指出无法根据用法推断出该类型.

我想要实现的是让它们同时运行,因为它们都是非常长的进程,然后运行 aurelia.start()

bas*_*rat 48

这是TypeScript及其Promise.all签名的弱点.通常最好使阵列具有一致的类型.您可以手动执行以下操作:

let foo : [Promise<Aurelia>,Promise<void>] = [aurelia.start(), entityManagerProvider.initialize()];
Promise.all(foo).then((results:any[]) => {
    let aurelia: any = results[0];
    aurelia.setRoot();
});
Run Code Online (Sandbox Code Playgroud)

  • 看起来这对我来说现在只有纯粹的推论.它返回一种Promise <[T1,T2]>类型,效果很好.我不确定这是由于最近的编译器功能还是仅仅因为ES6承诺的类型现在比以前更好.无论如何,这里的推论令人印象深刻. (2认同)
  • -1:通过Promise.all &lt;T,Y,Z,number,...&gt;键入比首先声明一个类型化的promises更简单。查看答案:/sf/answers/2830127051/ (2认同)

And*_*ard 31

既然Promise::all是泛型函数,您可以声明每个promise的返回类型,如下所示:

Promise.all<Aurelia, void>([
  aurelia.start(),
  entityManagerProvider.initialize()
])
.then(([aurelia]) => aurelia.setRoot());
Run Code Online (Sandbox Code Playgroud)

  • 在Typescript`2.7.2`中,我发现它能够正确地推断传递到`then()`块的数组中的类型,甚至不必将'类型'提前声明'作为通用参数.无极:: all`. (3认同)

Joh*_*isz 7

如果您希望保持类型安全性,则可以使用额外的重载签名扩展Promise对象(类型PromiseConstructor)的本机类型定义,以便在Promise.all使用有限数量的不一定可分配值调用时:

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]>;
    ...
}
Run Code Online (Sandbox Code Playgroud)

根据需要添加尽可能多的重载.此方法为回调value参数中的所有元素提供完全类型安全性onfulfilled:

Promise.all([1, "string", true]).then(value =>
{
    let a: number = value[0]; // OK
    let b: number = value[1]; // Type 'string' is not assignable to type 'number'.
    ...
});
Run Code Online (Sandbox Code Playgroud)

  • 我认为这是一个优雅的解决方案。 (2认同)

joo*_*.fi 7

至少从TypeScript 2.7.1开始,编译器似乎在没有帮助的情况下解析类型,语法如下:

Promise.all([fooPromise, barPromise]).then(([foo, bar]) => {
  // compiler correctly warns if someField not found from foo's type
  console.log(foo.someField);
});
Run Code Online (Sandbox Code Playgroud)

帽子提示:@JamieBirch(来自评论@ AndrewKirkegaard的回答)

  • 或者更好的是 `const results: [foo, bar] = wait Promise.all([fooPromise, barPromise]);` 稍微更新一下 (2认同)