3

For example I have voidFucntion1(), voidFunction2(), I want to

Observable.forkJoin([voidFunction1(), voidFunction2()]).subscribe() ;

However this is not working at all, so how to cast void functions ? without changing the original voidFunction() ?

tomriddle_1234
  • 3,145
  • 6
  • 41
  • 71
  • 1
    In order to use `forkJoin` your functions needs to return and `observable`... – Hackerman Feb 08 '17 at 17:09
  • can I cast void function to observable? using `Observable.of()`? Will it work? – tomriddle_1234 Feb 08 '17 at 17:13
  • Maybe have a look at this with example of `forkJoin()` and more example http://stackoverflow.com/questions/42035075/observable-subscription-not-getting-called/42038302#42038302 – martin Feb 08 '17 at 17:21

2 Answers2

3

First of all: I highly suggest, that you do refactor your void-functions, other than that, it is kind of possible to use void-functions in a stream, even though it makes no sense whatsoever:

The only thing you can do with void-function in rxjs is the do-operator and the defer-operator:

Rx.Observable.defer(() => {
  voidFunction1();
  voidFunction1();
  return Rx.Observable.of("Done");
})
.subscribe(console.log);

function voidFunction1() {
  console.log("Called VoidFunc");
  // I'm not enjoyed
  // because I'm void!
}
<script src="https://unpkg.com/rxjs/bundles/Rx.min.js"></script>

If you have to use forkJoin:

const voidWrapper$ = wrapVoid(voidFunc);
const voidWrapper2$ = wrapVoid(voidFunc);

Rx.Observable.forkJoin(voidWrapper$, voidWrapper2$)
.subscribe(console.log);


function wrapVoid(func) {
  return Rx.Observable.defer(() => {
    func();
    return Rx.Observable.of("Done");
  })
}

function voidFunc() {
  console.log("called voidFunc");
  // notn' ho!
}
<script src="https://unpkg.com/rxjs/bundles/Rx.min.js"></script>
olsn
  • 16,644
  • 6
  • 59
  • 65
  • thanks again, propbally becoz im from C like funtional programming background , id make sure those functions are standalone reusable so i ask this. in my point of view the subscribe in a void will make sure it finishes its job in these void sub procedure. if i follow the reactive way, i have to think the future usage of a function for only part of the whole thing, such i tend to not to. am i wrong? – tomriddle_1234 Feb 09 '17 at 07:32
  • That is incorrect - if you have something async going on (like a subscribption) inside a void function there is absolutely no way of knowing when the async function inside the void is complete - wrapping the void as an Obsersevable has no effect on the execution at all! The only way of knowing this with 100% certainty is the case where in inner workings of your void are all executed synchronously ... in which case you do not the to use rxjs but can simple write the 2 method-calls after each other and have the very same result. – olsn Feb 09 '17 at 07:43
  • Also as a sidenote: functional programming (at least __any__ I have encountered so far) does not preach void functions as best-practice - a void function requires either: Data-Mutation (which is bad) or stateful Objects (which is the definition of NON-functional) - a proper, non-context-related, reusable function is _pure_, it takes a set of input(s), performs some calculations and returns the result of those calculations as output - it is independent from any state and does not mutate any of its inputs. – olsn Feb 09 '17 at 07:48
  • im writing REST API queries groups, each void is already done with a series of async communication, and now i wish to make these group run synchronously, so here comes the problem. i d like to ask if there's a way to make sure each subscribe execute finishes? make the void into promise and use then()? – tomriddle_1234 Feb 09 '17 at 08:06
  • There are so many ways to do this, to name some: return a Promise, return an Observable, take a callback, implement an event-listener, use the async/await-notation(will require transpilation to ES5) - since you are already using RxJS in other parts, it made the most sense to return an Observable here. – olsn Feb 09 '17 at 08:10
  • defer will work i see but.why forkjoin with void.wrapper will work? statements in subscribe after forkjoin runs before voidwrappers? – tomriddle_1234 Feb 09 '17 at 08:27
  • ... __none__ of the above will work for your usecase, because they are all executed synchronously but your methods contain asynchronous execution-logic - this answer was just to demonstrate an example of what might work _technically_ for _some usecases_ - in __both__ examples will the subscription-callbacks be executed __before__ any other async task (rest-call, timeout, whatever...) is finished! – olsn Feb 09 '17 at 08:31
2

Forkjoin will wait for all of the observables to resolve before it will execute the callback function.

If you have "void" observables that never return, the forkjoin will hang. You need to make those functions have a resolution, even if they don't "return" anything.

chrispy
  • 3,552
  • 1
  • 11
  • 19