Francisco Souza
Francisco Souza

Reputation: 828

How to subscribe several Observables in an array but one at a time?

I have a list of tasks in array and I need to run them making a call to a web service.

But the thing is, they are in an array and I need to run one at a time, meaning: only run the next one when this one is finished, no matter if an error occurred or not.

I have this code here where I use combineLatest, but this way I only get the result when ALL them are finished.

let arrayOfTasks: ServerTask[] = cacheInfo.cacheData;
let observables = [];
arrayOfTasks.forEach((task: ServerTask) => {
  if (task.method === 'post') {
    let observable$: any = this.restService.sendPost(task.action, task.payload, false, task.cacheName);
    observables.push(observable$);
  }
});

const combined = combineLatest(observables);
combined.subscribe((value: any[]) => {
  console.log('ARRAY DATA RETURNED');
  console.log(value);
}, error => {
  console.error(`Error running stored tasks: ${error}`);
}, () => {
  console.log('All cache tasks executed...');
});

Any thoughts?

Edit 1:

As suggested by @trichetriche here is the final solution:

concat(...observables).subscribe((result: any) => {
  console.log('RESULT: ', result);
}, error => {
  console.error(`Error running queue of tasks: ${error}`)
}, () => {
  console.log('All subscriptions executed');
});

Upvotes: 0

Views: 62

Answers (1)

user4676340
user4676340

Reputation:

you can use concat for that, coupled with an array reducer :

obs$
  .reduce((acc, curr) => acc.pipe(concat(curr)), of(undefined))
  .subscribe(result => console.log(result));

You can even use the creator concat instead of the operator :

concat(...obs$)
  .subscribe(res => console.log(res));

Working stackblitz

Upvotes: 6

Related Questions