[英]How to create Observable from function?
I want to call a function (synchronously) and then use its return value as an initial emission (subsequently chaining some other operators on the resulting observable).我想调用一个函数(同步),然后使用它的返回值作为初始发射(随后在结果 observable 上链接一些其他运算符)。
I want to invoke this function during subscription, so I can't just use Observable.of(() => getSomeValue())
.我想在订阅期间调用这个函数,所以我不能只使用
Observable.of(() => getSomeValue())
。 I've seen bindCallback
(previously fromCallback
) but I don't think it can be used for this task (correct me if I'm wrong).我见过
bindCallback
(以前是fromCallback
),但我认为它不能用于此任务(如果我错了,请纠正我)。 I've seen start
static operator in v4 docs but apparently it is not implemented in v5 (and no indication that its on the way).我已经在 v4 文档中看到了
start
static 运算符,但显然它没有在 v5 中实现(并且没有迹象表明它在路上)。 RxJava also has fromCallable
operator that does exactly that afaik. RxJava 也有
fromCallable
运算符,它完全可以fromCallable
这一点。
Only way I could think of is like this:我能想到的唯一方法是这样的:
Observable.create((observer: Observer<void>) => {
let val = getSomeValue();
observer.next(val);
observer.complete();
})
which I think does just that.我认为就是这样做的。 But this just seems so complicated for a simple thing that should probably have been like
Observable.fromFunction(() => getSomeValue())
And what if I want to run it asynchronously, like start
operator does?但这对于一个简单的事情来说似乎太复杂了,应该像
Observable.fromFunction(() => getSomeValue())
如果我想异步运行它怎么办,就像start
操作符那样? How can I do this in the current version of RxJS?如何在当前版本的 RxJS 中执行此操作?
I tend to avoid any explicit use of Observable.create
where ever possible, because generally it is a source of bugs to have to manage not just your event emission but also your teardown logic.我倾向于尽可能避免任何显式使用
Observable.create
,因为通常它是错误的来源,不仅要管理您的事件发射,还要管理您的拆卸逻辑。
You can use Observable.defer
instead.您可以改用
Observable.defer
。 It accepts a function that returns an Observable
or an Observable-like
thing (read: Promise, Array, Iterators).它接受一个函数,该函数返回一个
Observable
或Observable-like
东西(读作:Promise、Array、Iterators)。 So if you have a function that returns an async thing it is as easy as:因此,如果您有一个返回异步事物的函数,则很简单:
Observable.defer(() => doSomethingAsync());
If you want this to work with a synchronous result then do:如果您希望它与同步结果一起使用,请执行以下操作:
Observable.defer(() => Observable.of(doSomethingSync()));
Note: That like create
this will rerun the function on each subscription.注意:就像
create
this 将在每个订阅上重新运行该函数。 This is different then say the result of Observable.bindCallback
which stores the function call result without re-executing the function.这与
Observable.bindCallback
的结果不同,它存储函数调用结果而不重新执行函数。 So if you need that sort of behavior you will need to use the appropriate multicasting
operator.因此,如果您需要这种行为,则需要使用适当的
multicasting
运算符。
An implementation of a fromFunction$
that I used in my project:我在项目中使用的
fromFunction$
的实现:
function fromFunction$<T>(factory: () => T): Observable<T> {
return Observable.create((observer: Subscriber<T>) => {
try {
observer.next(factory());
observer.complete();
} catch (error) {
observer.error(error);
}
});
}
Used like:像这样使用:
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}`));
Gives:给出:
Value is '0'
Completed
Value is '1,2,3'
Completed
Error: Something
Until such implementation exists.直到存在这样的实现。
Actually I think the best option is using Observable.create
because it's the most universal solution for both synchronous and asynchronous initial values.实际上我认为最好的选择是使用
Observable.create
因为它是同步和异步初始值的最通用的解决方案。
If you're sure you'll use a synchronous function you can use startWith()
operator (this makes sence only if return value from getSomeValue()
should be the same for all Observers).如果您确定要使用同步函数,则可以使用
startWith()
运算符(只有当getSomeValue()
返回值对于所有观察者都应该相同时, getSomeValue()
)。
Using Observable.bindCallback
as a source Observable is of course doable however I personally recommend to avoid it because it makes your code very hard to understand and it's usually not necessary because you can use just Observable.create
.使用
Observable.bindCallback
作为源 Observable 当然是可行的,但我个人建议避免它,因为它会使你的代码很难理解,而且通常没有必要,因为你可以只使用Observable.create
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.