typescript - 在 Typescript 中运行一批 Promise
问题描述
我的 Typescript 项目中有一系列 Promises。
大多数时候,我使用 Promise.all() 来并行执行所有这些:
let promises:Array<Promise<string>> = ....
Promise.all(promises)
.then(results:Array<string> => ....)
.catch(error => ....)
我必须通过以 3 的并发运行来执行一系列 Promise 来减少背压。
我想保持没有依赖关系,但如果你有一个通过 dep 的解决方案,请随意。
我尝试使用es6-promise-pool但我似乎还没有为 Typescript 准备好
import PromisePool = require('es6-promise-pool')
const promiseProducer = () => {
if (commands.length > 0) {
return commands.shift()
} else {
return null
}
}
let concurrency = 3;
let pool = new PromisePool(promiseProducer, concurrency)
此表达式不可构造。类型 'typeof import("..../node_modules/es6-promise-pool/es6-promise-pool")' 没有构造签名。
我已经根据@jfriend00 的评论实现了mapConcurrent()函数。
function mapConcurrent(items: Array<any>, maxConcurrent: number, fn: any): Promise<Array<any>> {
let index = 0;
let inFlightCntr = 0;
let doneCntr = 0;
let results = new Array(items.length);
let stop = false;
return new Promise((resolve, reject) => {
const runNext = () => {
let i = index;
++inFlightCntr;
fn(items[index], index++).then(function (val: any) {
++doneCntr;
--inFlightCntr;
results[i] = val;
run();
}, function (err: any) {
stop = true;
reject(err);
});
}
const run = () => {
while (!stop && inFlightCntr < maxConcurrent && index < items.length) {
runNext();
}
if (doneCntr === items.length) {
resolve(results);
}
}
run();
});
}
然后我能够按预期运行承诺
let array = [1,2,3,4,5,6,7,8,9,10]
const maxConcurrency = 3
mapConcurrent(array, maxConcurrency , (index: number) => myPromise(index))
.then((results: Array<any>) => {
//... do stuff with results ...
}).catch(error => { reject(error) })
根据 Typescript,只缺少一个东西,有没有办法为 Promise 结果获取 Promise 类型的数组?
如果我的 promise 的类型是 <{id:string}>,我们可以得到类型为 Array<{id:string}> 的结果吗?
实际上 mapConcurrent() 只解析类型 Array
解决方案
随着打字
function mapConcurrent<T>(items: Array<string>, maxConcurrent: number, fn: (item: string) => Promise<T>): Promise<Array<T>> {
let index = 0;
let inFlightCntr = 0;
let doneCntr = 0;
let results = new Array(items.length);
let stop = false;
return new Promise((resolve, reject) => {
const runNext = () => {
let i = index;
++inFlightCntr;
fn(items[index])
.then(result => {
++doneCntr;
--inFlightCntr;
results[i] = result;
run();
})
.catch(error => {
stop = true;
reject(error);
});
index++
}
const run = () => {
while (!stop && inFlightCntr < maxConcurrent && index < items.length) {
runNext();
}
if (doneCntr === items.length) {
resolve(results);
}
}
run();
});
}
推荐阅读
- azure-active-directory - 为资源“组”的属性“可见性”指定了不受支持或无效的查询过滤器子句
- hyperledger - 如何安装超级账本资源管理器并将其集成到 iroha?
- python - 如何在 PySpark 中编码 DateTime 值?
- excel - VBA在最后一列之后创建两列,带有数据的特定行
- python - 我可以安全地忽略这些错误吗?
- angular - 使用路由参数的角度路由路径匹配
- c# - 泛型。调用一个方法两次,但每次参数都是不同的类型
- arrays - 如何遍历哈希数组以在 ruby 中查找用户名?
- opencv - 如何分割图像以使结果只是分割后的图像(没有任何背景)
- python - 如何将 sympy 表达式转换为图形?