Я пытаюсь выполнить асинхронные манипуляции со строками в массиве. Класс имеет массив объектов, у которых есть метод преобразования, возвращающий наблюдаемую величину. Каждый вызов преобразования зависит от результата предыдущего.
Моей первой мыслью было использовать concatMap
, но поскольку наблюдаемые должны быть созданы с выводом предыдущего, я не верю, что смогу использовать этот оператор.
Используя concatMap, это будет выглядеть примерно так:
return of([initialStr])
.pipe(
concatMap(strArr => this.stringTransformers[0].transform(strArr)),
concatMap(strArr => this.stringTransformers[1].transform(strArr)),
concatMap(strArr => this.stringTransformers[2].transform(strArr)),
... until the end of the stringTransformers array
));
Как я могу воссоздать шаблон concatMap
выше, но динамически масштабировать его в соответствии с размером массива?
🤔 А знаете ли вы, что...
JavaScript можно использовать для создания видеоигр, как 2D, так и 3D, с использованием библиотеки Three.js.
Это моя версия решения. Я использую expand для рекурсивного вызова наблюдаемого массива до тех пор, пока не останется элементов, затем я использую last для вывода окончательного значения.
import { concatMap } from 'rxjs/operators';
import './style.css';
import { rx, of, map, expand, EMPTY, last } from 'rxjs';
const initialStr = 'hello';
const stringTransformers = [
{
transform: (inputs: Array<string>) =>
of(inputs.map((input: string) => `${input}-1`)),
},
{
transform: (inputs: Array<string>) =>
of(inputs.map((input: string) => `${input}-2`)),
},
{
transform: (inputs: Array<string>) =>
of(inputs.map((input: string) => `${input}-3`)),
},
{
transform: (inputs: Array<string>) =>
of(inputs.map((input: string) => `${input}-4`)),
},
{
transform: (inputs: Array<string>) =>
of(inputs.map((input: string) => `${input}-5`)),
},
];
of([initialStr])
.pipe(
expand((value: Array<string>, index: number) => {
return stringTransformers[index]
? stringTransformers[index].transform(value)
: EMPTY;
}),
last()
)
.subscribe((output) => console.info('final', output));
Я думаю, что ваш подход верен, и для создания динамического канала я бы использовал редуктор для создания канала из трансформатора, просто перенаправляя наблюдаемые друг на друга.
Stackblitz (повторное использование демо от @NarenMurali, спасибо).
stringTransformers
.reduce(
(obs, transformer) =>
obs.pipe(concatMap((value) => transformer.transform(value))),
of([initialStr])
)
.subscribe((output) => console.info('final', output));