Javascript 使用Rxjs以延迟方式并行调用同步请求块?

Javascript 使用Rxjs以延迟方式并行调用同步请求块?,javascript,angular,rxjs,rxjs5,Javascript,Angular,Rxjs,Rxjs5,我有一个任务队列(长度为20),其中每个任务都是要调用的ajax请求 我想: 1) 创建5个块(20/5=4个块) 2) 执行每个区块,区块中的每个项目将以1000毫秒的延迟执行。 3) 当每个区块项目完成时,等待3秒钟 因此: 1..1秒(↦ 绿色)…2..1秒(↦ 绿色)…3..1秒(↦ 绿色)…4..1秒(↦ 绿色)…5..3秒……… 6..1秒(↦ 绿色)…7..1秒(↦ 绿色)…8..1秒(↦ 绿色)…9..1秒(↦ 绿色)…10。。。。。。。。。。。。。。。。。。。。。3秒。。。。。

我有一个任务队列(长度为20),其中每个任务都是要调用的ajax请求

我想:

1) 创建5个块(20/5=4个块)
2) 执行每个区块,区块中的每个项目将以1000毫秒的延迟执行。
3) 当每个区块项目完成时,等待3秒钟

因此:

1..1秒(↦ 绿色)…2..1秒(↦ 绿色)…3..1秒(↦ 绿色)…4..1秒(↦ 绿色)…5..3秒………
6..1秒(↦ 绿色)…7..1秒(↦ 绿色)…8..1秒(↦ 绿色)…9..1秒(↦ 绿色)…10。。。。。。。。。。。。。。。。。。。。。3秒。。。。。。。。。。 ... 11..1秒(↦ 绿色)…12..1秒(↦ 绿色)…13..1秒(↦ 绿色)…14..1秒(↦ 绿色)…15。。。。。。。。。。。。。。。。。。。。。3sec………
16..1秒(↦ 绿色)…17..1秒(↦ 绿色)…18..1秒(↦ 绿色)…19..1秒(↦ 绿色)…20

我确实做了一些接近的事情:

与:

from(this.httpCodes)
      .pipe(bufferCount(5),
       concatMap((i, y) => from(i).pipe(mergeMap(f => {
                                    this.httpCodes[f.index].wasExecuted = true;
                                     return this.ajaxAlike(f.data).pipe(
                                                               catchError(() => { return of(-1) }),
                                                               map((r) => ({ res: r, data: f }))
                                                                      )
                                                      }) 
                                        ,delay(3000) )),

      )
但它并没有按照我的意图执行。我看不到区块中每个项目之间的延迟

问题:

为什么我会看到这么多请求,如何更改代码,使块中的每个项目都能以1秒的延迟执行(每秒钟后都会出现绿色),并且-在每个块之后,等待3秒


编辑:好吧,我想我现在明白你的意思了。我更新了fiddle,这样所有的块部分都可以并行执行,但是块会互相等待完成。因此,这应该可以做到:

const chunkSize = 5;
const requestsWithDelay = httpRequests.map(obs => obs.delay(1000));

let chunks = [];
for (let i = 0; i < requestsWithDelay.length; i += chunkSize) {
    chunks.push(requestsWithDelay.slice(i, i + chunkSize));
}

const chunkedRequests = chunks.map(chunk => Rx.Observable.forkJoin(...chunk).delay(3000));
const parallelChunkRequest = Rx.Observable.concat(...chunkedRequests);
parallelChunkRequest.subscribe();
但如果您希望块并行执行,您可以执行以下操作:

let chunks = [];
for (let i = 0; i < requestsWithDelay.length; i += 5) {
    chunks.push(requestsWithDelay.slice(i, i + 5));
}

const chunkedRequests = chunks.map(chunk => Rx.Observable.concat(...chunk));
const parallelChunkRequest = Rx.Observable.merge(...chunkedRequests);
let chunk=[];
for(设i=0;iRx.Observable.concat(…chunk));
const parallelChunkRequest=Rx.Observable.merge(…chunkedRequests);
我创造了一个


但是,如果它们并行执行并且不互相等待,那么为什么在每个块之后都需要3秒的延迟呢?

delay操作符延迟发出的项。您似乎希望它发出该项,然后在发出下一项之前“休眠”3秒钟。要实现这一点,您可以捕获一个空的延迟可观测值

您可以创建以下可管道睡眠操作符:

const sleep = ms => concat(Rx.Observable.empty().pipe(delay(ms)))
并按如下方式使用:

const{concatMap,concat,delay,bufferCount}=Rx.operators;
const sleep=ms=>concat(Rx.Observable.empty().pipe(delay(ms));
const ajaxlike=call=>Rx.Observable.of(call.pipe)(延迟(500));
Rx.可观测范围(0,20).管道(
缓冲计数(5),
concatMap(调用=>
接收。可观察。来自(呼叫)。管道(
concatMap(call=>ajaxlike(call).pipe(sleep(1000)),
睡眠(3000)
)
)
)
.subscribe(console.log)

因为我不想让服务器认为im淹没了itI,我在开始时没有真正理解问题,认为区块应该并行运行,但不是每个区块的内容。每个项目之间的1秒延迟是什么?ajax延迟只是对ajax的模拟……我想发出ajax请求,并在下一个请求之前等待1秒。换句话说,假设AjaxSimple方法没有延迟,我仍然想在ajax发出后等待1秒。换句话说,要看到绿色,然后等待1秒。不发射,等待1秒,然后绿色显示“1..1秒(↦ 绿色)“让我觉得你想在绿色之前延迟1秒。我修改了我的答案。
let chunks = [];
for (let i = 0; i < requestsWithDelay.length; i += 5) {
    chunks.push(requestsWithDelay.slice(i, i + 5));
}

const chunkedRequests = chunks.map(chunk => Rx.Observable.concat(...chunk));
const parallelChunkRequest = Rx.Observable.merge(...chunkedRequests);
const sleep = ms => concat(Rx.Observable.empty().pipe(delay(ms)))