Несколько вызовов функций с Promise.all - PullRequest
0 голосов
/ 28 октября 2019

У меня есть несколько функций, таких как следующие

private async p1(): Promise<Result> {
    let p1;
    // Do stuff.

    return p1;
}

private async p5(): Promise<void> {
    // Call some external API.

}

Некоторые из них имеют return, некоторые нет. Но все они делают что-то очень специфичное, и они не зависят друг от друга.

Я пытаюсь вызвать их все асинхронно с Promise.all () и выполнить их параллельно (с быстрым сбоембезопасный). У меня до 15 звонков, например, следующий фрагмент:

    let [x1, x2, x3] = await Promise.all([
        this.p1,
        this.p2,
        this.p3,
        this.p4,
        this.p5,
        this.p6,
        this.p7,
        this.p8,
        ...
        this.p15
    ]);

Однако меня приветствуют

src/app/view-models/index.ts:69:37 - error TS2345: Argument of type '(Promise<void> | Promise<Result>)[]' is not assignable to parameter of type 'Iterable<void | PromiseLike<void>>'.
  Types of property '[Symbol.iterator]' are incompatible.
    Type '() => IterableIterator<Promise<void> | Promise<Result>>' is not assignable to type '() => Iterator<void | PromiseLike<void>>'.
      Type 'IterableIterator<Promise<void> | Promise<Result>>' is not assignable to type 'Iterator<void | PromiseLike<void>>'.
        Types of property 'next' are incompatible.
          Type '(value?: any) => IteratorResult<Promise<void> | Promise<Result>>' is not assignable to type '(value?: any) => IteratorResult<void | PromiseLike<void>>'.
            Type 'IteratorResult<Promise<void> | Promise<Result>>' is not assignable to type 'IteratorResult<void | PromiseLike<void>>'.
              Type 'Promise<void> | Promise<Result>' is not assignable to type 'void | PromiseLike<void>'.
                Type 'Promise<Result>' is not assignable to type 'void | PromiseLike<void>'.
                  Type 'Promise<Result>' is not assignable to type 'PromiseLike<void>'.
                    Types of property 'then' are incompatible.
                      Type '<TResult1 = Result, TResult2 = never>(onfulfilled?: ((value: Result) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined) => Promise<...>' is not assignable to type '<TResult1 = void, TResult2 = never>(onfulfilled?: ((value: void) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined) => PromiseLike<...>'.
                        Types of parameters 'onfulfilled' and 'onfulfilled' are incompatible.
                          Types of parameters 'value' and 'value' are incompatible.
                            Type 'Result' is not assignable to type 'void'.

 69         const x = await Promise.all([
                                        ~
 70             this.p1,
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...
 81             this.p15
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 82         ]);

Если я попытаюсь добавить только (до) 11 звонков,ЛЮБОЙ из них все работает как положено. Как только я добавляю вызов 12-й функции, возникает вышеуказанная ошибка.

Есть что-то, чего мне не хватает, или какой-нибудь обходной путь?

Ответы [ 2 ]

1 голос
/ 28 октября 2019

Кажется, что типы кортежей (гетерогенные массивы, где каждый элемент имеет свой собственный тип) поддерживаются только для двенадцати элементов. Или, по крайней мере, объявления перегрузки Promise.all на этом заканчиваются, и Typescript предполагает, что вы должны передавать список (произвольной длины, только с одним типом элемента).

Довольно простой обходной путь - это вложитьPromise.all структура:

let [x1, x2, x3, _] = await Promise.all([
    this.p1,
    this.p2,
    this.p3,
    Promise.all([
        this.p4,
        this.p5,
        this.p6,
        this.p7,
        this.p8,
        ...
        this.p15
    ]),
]);
0 голосов
/ 28 октября 2019

Мне удалось воспроизвести это, как только вы нажмете 11 элементов. Встроенный заголовок lib.es2015.promise.d.ts включает в себя перегрузки до 10 элементов, но , как Берги упоминает , как только вы нажмете 11, он предполагает, что списокэлементы являются однородными.

В дополнение к вложению Promise.all вы также можете использовать явное обобщение для ввода возвращаемых значений как unknown. При этом вы не сможете выполнять какие-либо значимые операции с элементами списка, но если вы не собираетесь извлекать из списка конкретные результаты, которые не должны иметь большого значения.

// bar is of type Promise<unknown[]>
let bar = Promise.all<unknown>([foo1(), foo2(), foo3(), foo4(), foo5(),
    foo6(), foo7(), foo8(), foo9(), foo10(), foo11(), foo12(), foo13(),
    foo14(), foo15()]);

машинопись игровая площадка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...