Выполнить пакет с обещаниями в Typescript - PullRequest
0 голосов
/ 19 марта 2020

У меня есть массив Обещаний в моем проекте Typescript.

Большую часть времени я использую Promise.all () для параллельного выполнения всех из них:

let promises:Array<Promise<string>> = ....
Promise.all(promises)
  .then(results:Array<string> => ....)
  .catch(error => ....)

Я должен уменьшить обратное давление, выполняя массив обещаний, выполняя их с параллелизмом 3.

Я бы хотел остаться без зависимостей, но если у вас есть решение через dep, не стесняйтесь.


Я пытался использовать es6-обещание-пул , но мне кажется, что он не готов для 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") "не имеет конструктивных подписей.


Я реализовал mapConcurrent () функция в соответствии с комментарием @ jfriend00.

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 для результатов обещания?

Если мое обещание имеет тип <{id: string}>, мы можем получить результат с типом Array <{id : string}>?

На самом деле mapConcurrent () разрешает только тип Array

1 Ответ

0 голосов
/ 08 апреля 2020

С набором

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