loading...

Enforce order on async operations

mrcoder profile image Peng Xiao ・1 min read

Say we have two methods: foo and bar

const foo = function() {
  setTimeout(() => {
    console.log('foo')
  }, 100)
}

const bar = function() {
  setTimeout(() => {
    console.log('bar')
  }, 50)
}

We want to make sure that 'foo' is printed before 'bar'.

Here is how you can do it with rxjs (6.5).

import {of, defer, Subject} from 'rxjs'
import {concatAll} from 'rxjs/operators'
const foo = function() {
  const subjectFoo = new Subject()
  setTimeout(() => {
    subjectFoo.next('foo')
    subjectFoo.complete()
  }, 100)
  return subjectFoo
}

const bar = function() {
  const subjectBar = new Subject()
  setTimeout(() => {
    subjectBar.next('bar')
    subjectBar.complete()
  }, 100)
  return subjectBar
}

const source = of(defer(foo), defer(bar))
source.pipe(concatAll()).subscribe(console.log)

I know I am changing the signature of foo and bar. This might not be possible in some cases.

A few things to note:

  1. Let your function return a Subject;
  2. Complete the Subject in the callback of the async operation;
  3. defer the functions and build a observable; make sure you put them in the right order
  4. Concat all of them with pipe(concatAll()
  5. Subscribe to the final observable.

Posted on May 16 by:

mrcoder profile

Peng Xiao

@mrcoder

Founder of ZenUML.com

Discussion

markdown guide