如何在 Typescript 中使用 Promise.all()

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33684634/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 06:49:18  来源:igfitidea点击:

How to use Promise.all() with Typescript

typescript

提问by Greg Gum

Here is what I want to do:

这是我想要做的:

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

aurelia.start()returns an Aurelia type, while initialize()returns void.

aurelia.start()返回一个 Aurelia 类型,而initialize()返回 void。

The compiler gives an error message that the type cannot be inferred from the usage.

编译器给出了一个错误消息,表明无法从用法推断出类型。

What I am trying to achieve is to get them to run at the same time, as they are both very long processes, then run Aurelia.setRoot();

我想要实现的是让它们同时运行,因为它们都是很长的进程,然后运行 Aurelia.setRoot();

回答by basarat

This is a weakness in the TypeScript and its Promise.allsignature. Its generally best to have arrays with consistent types. You can do the following manually though:

这是 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();
});

回答by Andrew Kirkegaard

Since Promise::allis a generic function, you can declare the return types of each promise like this:

由于Promise::all是一个泛型函数,你可以像这样声明每个 promise 的返回类型:

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

回答by joonas.fi

At least from TypeScript 2.7.1onwards, the compiler seems to resolve the types without help, with a syntax like this:

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

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

Hat tip: @JamieBirch (from comment to @AndrewKirkegaard's answer)

帽子提示:@JamieBirch(从评论到@AndrewKirkegaard 的回答)

回答by John Weisz

If you'd like to keep type-safety, it's possible to extend the native type-definitionof the Promiseobject (of type PromiseConstructor) with additional overload signatures for when Promise.allis called with a finite number of not-necessarily inter-assignable values:

如果您想保持类型安全,可以使用额外的重载签名扩展Promise对象( type PromiseConstructor的本机类型定义,用于 whenPromise.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]>;
    ...
}

Add as many overloads as you need. This approach provides full type-safety for all elements in the valueargument of the onfulfilledcallback:

根据需要添加尽可能多的重载。这种方法为回调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'.
    ...
});

回答by Paul T. Rawkeen

I somehow landed here when I was looking for return type of Promise.all()since straightforward [Promise<any>, Promise<any>]is obviously not working.

当我寻找返回类型时,我不知何故来到这里,Promise.all()因为直接[Promise<any>, Promise<any>]显然是行不通的。

Eventually it turned out to be simplier than it seems:

最终结果证明它比看起来更简单:

const severalMongoDbOperations: Promise<[DeleteWriteOpResultObject, UpdateWriteOpResult]> =
  () => Promise.all([
    mongo.deleteOne({ ... }),
    mongo.updateOne({ ... })
  ]);

Later it can be used with .then()or:

稍后它可以与.then()or一起使用:

try {
  const ops: [DeleteWriteOpResultObject, UpdateWriteOpResult] = await severalMongoDbOperations();
} catch (e) {
  // Process rejection
}