Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

90
Views
RxJS concat only emit on complete / the missing RxJS contactJoin

I've got an array of Observables and I'm trying to do 2 things:

(1) the subscribe block's next function should only be called once, when everything is done, with an array of all results.

(2) the Observables must be fired in sequence, not all at the same time.

Here's my code so far, where (1) is NOT working and (2) is working:

const nums = [1, 2, 3];

const obs$ = nums.map((num) => {
  return rxjs.defer(() => {
    // this is an async op, mimicking an HTTP call
    console.log('firing', num);
    return rxjs.from(
      new Promise((resolve) => setTimeout(() => resolve(num), 2000))
    );
  });
});

rxjs.concat(...obs$).pipe(
  // do something here?
).subscribe(
  num => { console.log('next', num) },
  err => { console.error('error', err.message) },
  () => { console.log('complete') }
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/7.5.6/rxjs.umd.min.js"></script>

Actual output:

at 0 secs ... firing 1
at 2 secs ... next 1
at 2 secs ... firing 2
at 4 secs ... next 2
at 4 secs ... firing 3
at 6 secs ... next 3
at 6 secs ... complete

Desired output:

at 0 secs ... firing 1
at 2 secs ... firing 2
at 4 secs ... firing 3
at 6 secs ... next [1, 2, 3]
at 6 secs ... complete

Note the timings are important here.

Now I know forkJoin combines results like this. The problem with forkJoin is that firing 1 firing 2 and firing 3 all happen at the same time but I need them to fire sequentially, which is why I am using concat.

How can I achieve the desired output whilst preserving the above desired timings for firing 1 firing 2 and firing 3?

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

Use toArray inside the pipe of concat it will execute each one and then call next after all are done!

const nums = [1, 2, 3];

const obs$ = nums.map((num) => {
  return rxjs.defer(() => {
    // this is an async op, mimicking an HTTP call
    console.log('firing', num);
    return rxjs.from(
      new Promise((resolve) => setTimeout(() => resolve(num), 500))
    );
  });
});

let output = [];
rxjs.concat(...obs$).pipe(
  rxjs.toArray(),
).subscribe(
  num => {
    console.log('next', num)
  },
  err => {
    console.error('error', err.message)
  },
  () => {
    console.log('complete')
  }
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/7.5.6/rxjs.umd.min.js"></script>

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!