Home > other >  Wait for resolving Observable for synchronous usage
Wait for resolving Observable for synchronous usage

Time:10-09

I like to resolve my Observable res$ before continue with log-ready. But I found no way, to achieve that. I can't move my last log-line into async context. Is there a way to solve that problem?

let o1 = Observable.create((o) => {
  console.log('o1 start');
  setTimeout(() => {
    console.log(`o1 is running`);
    o.next('o1');
  }, 1500);
  console.log('o1 ends');
});

let o2 = Observable.create((o) => {
  console.log('o2 starts');
  setTimeout(() => {
    console.log(`o2 is running`);
    o.next('o2');
  }, 1100);
  console.log('o2 ends');
});

let res$ = o1.pipe(concatMap(() => o2)).subscribe();
//ToDO resolve res$ before continue execution

console.log(`ready`);

https://stackblitz.com/edit/rxjs-b9z3wn?devtoolsheight=60

CodePudding user response:

Is there a way to solve that problem?

In short: No, this is impossible.


JavaScript is a single-theaded language. Asynchronous code is all run on the same thread such that two parts of your JavaScript code will never run at the same time.

This has some advantages. For example, you rarely need to worry about mutex's, semaphores, etc. With JavaScript you can be certain that all synchronous code will run to completion before any other code is run.

There is a downside, however, it's not possible to lift an asynchronous context into a synchronous one. Any attempt to do so will never halt (the way a program fails when you write an infinite loop). This is why Node.js was (still is for older code) infamous for callback hell. It relies heavily on shoving callbacks onto the event loop since it is never allowed to wait. Promises and Observables are two ways to manage this complexity.

JavaScript is single threaded. So if you wait for 10 seconds, the whole program will hang for 10 seconds and do nothing. If you try to wait for something else to happen, the single thread will be busy waiting for forever and therefore be too busy to go do the thing it's waiting for.

CodePudding user response:

You can convert an Observable to a Promise and await it afterwards. Try this:

await o1.pipe(concatMap(() => o2)).toPromise()
  • Related