Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.8k views
in Technique[技术] by (71.8m points)

rxjs - How to force observables to execute in sequence?

I am moving from the Promise world to the Observable world. One thing I usually do with Promise is to chain a series of tasks and make them run in sequence. For example, I have three tasks: printLog1() to print 1 to the console, printLog23() to print 2 and 3 to the console, and printLog4() to print 4.

When I want to print 1-2-3-4, I would write a promise chain like

printLog1()
  .then(() => {
    printLog23();
  })
  .then(() => {
    printLog4();
  });

Now I want the same functionality with Observable and I can rewrite the printLog() function into an Observable like

printLog1 = Rx.Observabale.of(1).map((i) => console.log(i));
printLog23 = Rx.Observabale.of(2, 3).map((i) => console.log(i));
printLog4 = Rx.Observabale.of(4).map((i) => console.log(i));

Then I have three observables that emits different values to the console. How do I chain them so that these three observables would run in order and print 1-2-3-4?

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If you want to be sure the order of emissions is the same as the order in which you specified the source Observables you can use concat or concatMap operators.

The concat* operators subscribe to an Observable only after the previous Observable completes (it works with Promises as well, see http://reactivex.io/rxjs/class/es6/MiscJSDoc.js~ObservableInputDoc.html).

In you case it'd look like the following:

import { concat } from 'rxjs'; // Note, concat from 'rxjs', is not the same as concat from 'rxjs/operators'

concat(printLog1, printLog23, printLog4);

... or with concatMap if the request for one Promise depends on the response from the previous Promise:

printLog1.pipe(
  concatMap(response => ...),
  concatMap(response => ...),
);

... or when the order doesn't matter you can use merge that subscribes to all Observables/Promises immediately and reemits their results as they arrive:

merge(printLog1, printLog23, printLog4);

Jan 2019: Updated for RxJS 6


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...