Я выяснил, что оператор, который я искал, - это ОбъединитьАлла (), а не toАррей () после оператора конкатат. У меня есть и другая реализация с обещаниями. Теперь я верю, что оба они должны работать, но я опубликую тот, в котором я уверен больше - это обещания.
Реализация, использующая обещания:
export const sentMessages$ = sendMessage$.pipe(
mergeMap(
(input: SendInfo):
Observable<(discord.Message | null)[]> => {
const chunks: string[] = input.content.match(regex) || [];
const observables: Observable<(discord.Message | null)[]>[] = chunks.map(
(chunk: string):
Observable<(discord.Message | null)[]> => {
const bound = input.message.channel.send.bind(
undefined,
chunk,
input.options,
);
// eslint-disable-next-line max-len
return Network.genericNetworkObservable<discord.Message | discord.Message[]>(
bound,
).pipe(
// eslint-disable-next-line comma-dangle
map((x): (discord.Message | null)[] => [x].flatMap(
(t): (discord.Message | discord.Message[] | null) => t
))
);
}
);
const promises = observables
.map(
(obs: Observable<(discord.Message | null)[]>):
Promise<(discord.Message | null)[]> => obs.toPromise()
);
const reduced = promises
.reduce(async (promiseChain, currentTask):
Promise<(discord.Message | null)[]> => [
...await promiseChain,
...await currentTask,
].flatMap((x): (discord.Message | null) => x));
return from(reduced);
}
),
share(),
);
Реализация двух чистых RxJ:
export const sentMessages$ = sendMessage$.pipe(
mergeMap(
(input: SendInfo):
Observable<(discord.Message | null)[]> => {
const chunks: string[] = input.content.match(regex) || [];
const observables: Observable<(discord.Message | null)[]>[] = chunks.map(
(chunk: string):
Observable<(discord.Message | null)[]> => {
const bound = input.message.channel.send.bind(
undefined,
chunk,
input.options,
);
// eslint-disable-next-line max-len
return Network.genericNetworkObservable<discord.Message | discord.Message[]>(
bound,
).pipe(
// eslint-disable-next-line comma-dangle
map((x): (discord.Message | null)[] => [x].flatMap(
(t): (discord.Message | discord.Message[] | null) => t
))
);
}
);
return concat(observables).pipe(
combineAll(),
map(x => x.flatMap(t => t)),
);
}
),
share(),
);
Я считаю, что обещания будут работать, потому что они сведены в явную цепочку. Я не уверен, что мне не хватает нюанса с оператором concat, поэтому я не уверен на 100%, что он будет работать. Тестовый стенд, который я написал, на самом деле не работает должным образом из-за неправильного понимания того, как выполняются обещания с оператором отсрочки в RxJ, но я получаю ожидаемый порядок в соответствии с моим стендом. Я считаю, что мое недоразумение стало причиной того, что я не смог придумать эти решения легко.
[2019-10-23T06:09:13.948] [FATAL] messageWrapper.ts:109 - [
{ channel: { send: [Function] }, content: 'msg7' },
{ channel: { send: [Function] }, content: 'msg8' },
{ channel: { send: [Function] }, content: 'msg9' }
]
[2019-10-23T06:09:14.243] [FATAL] messageWrapper.ts:109 - [
{ channel: { send: [Function] }, content: 'msg4' },
{ channel: { send: [Function] }, content: 'msg5' },
{ channel: { send: [Function] }, content: 'msg6' }
]
[2019-10-23T06:09:14.640] [FATAL] messageWrapper.ts:109 - [
{ channel: { send: [Function] }, content: 'msg1' },
{ channel: { send: [Function] }, content: 'msg2' },
{ channel: { send: [Function] }, content: 'msg3' }
]
✓ should execute concurrently. (753ms)