Arrays 在RxJs中,如何在按顺序返回结果数组的同时在合并映射中执行序列?

Arrays 在RxJs中,如何在按顺序返回结果数组的同时在合并映射中执行序列?,arrays,rxjs,observable,concat,mergemap,Arrays,Rxjs,Observable,Concat,Mergemap,我有一个函数,可以将一条消息分解为多个消息块。我需要这些消息被张贴,以便我的张贴功能。然而,我不希望被观察者阻止其他传入的帖子。我的解决方案是在mergemap中使用concat操作符的组合,但我似乎无法使它正常工作 我不确定我是否能绘制出一张图表,但以下是我的尝试: -1-2------3|-> --4--5--6|-> desired output: [4,5,6] [1,2,3] 我需要请求1在3之前执行2,在5之前执行4,在6之前执行。 在英语中,我想我会有一个可观测的可观

我有一个函数,可以将一条消息分解为多个消息块。我需要这些消息被张贴,以便我的张贴功能。然而,我不希望被观察者阻止其他传入的帖子。我的解决方案是在mergemap中使用concat操作符的组合,但我似乎无法使它正常工作

我不确定我是否能绘制出一张图表,但以下是我的尝试:

-1-2------3|->
--4--5--6|->
desired output:
[4,5,6]
[1,2,3]
我需要请求1在3之前执行2,在5之前执行4,在6之前执行。 在英语中,我想我会有一个可观测的可观测数据,我希望它映射到可观测数据流,然后映射到每个可观测输出流的标准数组。我只是不知道该怎么做。很长一段时间以来,我一直在混淆代码,试图将我刚才所说的概念化,以下是我最好的尝试:

接口发送信息{
信息:不和谐。信息
内容:字符串
选项?:discord.MessageOptions
}
export const sendMessage$:Subject=new Subject();
常量regex=/[\s\s]{11980}(?:\n |$)/g;
导出常量sentMessages$=sendMessage$.pipe(
合并地图(
(输入:SendInfo):
可观察=>{
常量块:字符串[]=input.content.match(regex)| |[];
const superObservable:Observable=concat(chunks.map(
(区块:字符串):
可观察=>{
const bound=input.message.channel.send.bind(
未定义,
大块
input.options,
);
返回网络.genericNetworkObservable(
跳跃
);
}
));
返回可观测的.pipe(
合并映射(e=>e),
toArray(),
);
}
),
点击((e):void=>Utils.logger.fatal(e)),
share(),
);
我的输出:

[2019-10-21T17:24:15.322] [FATAL] messageWrapper.ts:72 - [ { channel: { send: [Function] }, content: 'msg1' } ]
[2019-10-21T17:24:15.324] [FATAL] messageWrapper.ts:72 - [ { channel: { send: [Function] }, content: 'msg2' } ]
[2019-10-21T17:24:15.325] [FATAL] messageWrapper.ts:72 - [ { channel: { send: [Function] }, content: 'msg3' } ]

我觉得我接近一个解决方案,但我不知道如何准确地将其合并到单个数组中。我也不知道它在功能上是否正确

在这个问题上,我以前已经解决过维护秩序的问题

因此,使用我的parallelExecute,您可以将这些值减少为一个数组

parallelExecute(...yourObservables).pipe(
  reduce((results, item) => [...results, item], [])
);
下面是parallelExecute函数

const { BehaviorSubject, Subject } = rxjs;
const { filter } = rxjs.operators;

const parallelExecute = (...obs$) => {
  const subjects = obs$.map(o$ => {
    const subject$ = new BehaviorSubject();
    const sub = o$.subscribe(o => { subject$.next(o); });
    return { sub: sub, obs$: subject$.pipe(filter(val => val)) };
  });
  const subject$ = new Subject();
  sub(0);
  function sub(index) {
    const current = subjects[index];
    current.obs$.subscribe(c => {
      subject$.next(c);
      current.obs$.complete();
      current.sub.unsubscribe();
      if (index < subjects.length -1) {
        sub(index + 1);
      } else {
        subject$.complete();
      }
    });
  }
  return subject$;
}
const{BehaviorSubject,Subject}=rxjs;
const{filter}=rxjs.operators;
常量并行执行=(…obs$)=>{
const subjects=obs$.map(o$=>{
const subject$=新行为主体();
const sub=o$.subscribe(o=>{subject$.next(o);});
返回{sub:sub,obs$:subject$.pipe(filter(val=>val))};
});
const subject$=新主题();
亚组(0);
功能分组(索引){
常数当前=受试者[索引];
当前.obs$.subscribe(c=>{
主题$.next(c);
当前的.obs$.complete();
current.sub.unsubscribe();
if(指数<受试者长度-1){
分项指数(指数+1);
}否则{
主题$.complete();
}
});
}
返回主题$;
}

我发现我要找的运算符是combineAll()而不是concat语句后的toArray()。我还有另一个承诺的实现。现在我相信这两种方法都会奏效,但我会先发布一个我更确信的方法,那就是承诺

实施一使用承诺:

export const sentMessages$=sendMessage$.pipe(
合并地图(
(输入:SendInfo):
可观察=>{
常量块:字符串[]=input.content.match(regex)| |[];
const observables:Observable[]=chunks.map(
(区块:字符串):
可观察=>{
const bound=input.message.channel.send.bind(
未定义,
大块
input.options,
);
//eslint禁用下一行最大长度
返回网络.genericNetworkObservable(
跳跃
).烟斗(
//eslint禁用下一行逗号悬挂
映射((x):(discord.Message | null)[]=>[x]。平面映射(
(t) :(discord.Message | discord.Message[]| null)=>t
))
);
}
);
常数=可观测值
.地图(
(obs:可观察的):
Promise=>obs.toPromise()
);
const reduced=承诺
.reduce(异步(promiseChain,currentTask):
承诺=>[
…等待承诺链,
…等待当前任务,
].flatMap((x):(discord.Message | null)=>x);
返回(减少);
}
),
share(),
);
实现两个纯RXJ:

export const sentMessages$=sendMessage$.pipe(
合并地图(
(输入:SendInfo):
可观察=>{
常量块:字符串[]=input.content.match(regex)| |[];
const observables:Observable[]=chunks.map(
(区块:字符串):
可观察=>{
const bound=input.message.channel.send.bind(
未定义,
大块
input.options,
);
//eslint禁用下一行最大长度
返回网络.genericNetworkObservable(
[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)