如何从函数创建Observable?

时间:2017-01-02 19:31:00

标签: javascript rx-java rxjs system.reactive rxjs5

我想调用一个函数(同步),然后使用它的返回值作为初始发射(随后在生成的observable上链接其他一些运算符)。

我想在订阅期间调用此函数,因此我不能只使用Observable.of(() => getSomeValue())。我见过bindCallback(以前为fromCallback),但我不认为它可以用于此任务(如果我错了,请纠正我)。我在v4文档中看到了start静态运算符,但显然它没有在v5中实现(并且没有表明它在路上)。 RxJava还有fromCallable运算符,它确实完成了这一点。

我能想到的只有这样:

Observable.create((observer: Observer<void>) => {
  let val = getSomeValue();
  observer.next(val);
  observer.complete();
})

我认为就是这样。但这对于简单的事情来说似乎很复杂,应该像Observable.fromFunction(() => getSomeValue())那样,如果我想异步运行它,如start运算符那样呢?如何在RxJS的当前版本中执行此操作?

3 个答案:

答案 0 :(得分:15)

我倾向于尽可能避免明确使用Observable.create,因为通常它不仅需要管理事件发射而且还需要管理您的拆卸逻辑。

您可以改用Observable.defer。它接受一个返回ObservableObservable-like事物的函数(读取:Promise,Array,Iterators)。因此,如果您有一个返回异步事物的函数,它就像:

一样简单
Observable.defer(() => doSomethingAsync());

如果您希望使用同步结果,请执行以下操作:

Observable.defer(() => Observable.of(doSomethingSync()));

注意:与create类似,这将重新运行每个订阅的功能。这是不同的,然后说Observable.bindCallback的结果,它存储函数调用结果而不重新执行该函数。因此,如果您需要这种行为,则需要使用相应的multicasting运算符。

答案 1 :(得分:2)

我在项目中使用的fromFunction$的实现:

function fromFunction$(factory: () => any) {
  return Rx.Observable.create((observer) => {
    try {
      observer.next(factory());
      observer.complete();
    } catch (error) {
      observer.error(error);
    }
  });
}

用过:

fromFunction$(() => 0).subscribe((value) => console.log(`Value is '${value}'`), null, () => console.log('Completed'));
fromFunction$(() => [1, 2, 3]).subscribe((value) => console.log(`Value is '${value}'`), null, () => console.log('Completed'));
fromFunction$(() => { throw 'Something' }).subscribe(null, (error) => console.error(`Error: ${error}`));

给出:

Value is '0'
Completed

Value is '1,2,3'
Completed

Error: Something

直到存在此类实施。

答案 2 :(得分:1)

实际上我认为最好的选择是使用Observable.create,因为它是同步和异步初始值的最通用解决方案。

如果您确定要使用同步功能,可以使用startWith()运算符(仅当getSomeValue()的返回值对所有观察者都相同时才会出现这种情况。)

使用Observable.bindCallback作为源Observable当然是可行的,但是我个人建议避免它,因为它使您的代码很难理解,而且通常没有必要,因为您只能使用Observable.create。 / p>