如何在 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
How to use Promise.all() with 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.all
signature. 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::all
is 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.1
onwards, 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 Promise
object (of type PromiseConstructor
) with additional overload signatures for when Promise.all
is 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 value
argument of the onfulfilled
callback:
根据需要添加尽可能多的重载。这种方法为回调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
}