1 直接执行 / 转换
使用from
直接将先前创建的Promise转换为Observable。
import { from } from 'rxjs';
const observable$ = from(getPromise());
observable$
是一个热 Observable,它有效地将 Promise 的值重新发送给订阅者。
它是一个热 Observable,因为生产者(在这种情况下是 Promise)是在 Observable 外部创建的。多个订阅者将共享相同的 Promise。如果内部 Promise 已经解决,Observable 的新订阅者将立即获得其值。
2. 每次订阅时延迟执行
使用defer
和一个 Promise 工厂函数作为输入来延迟创建和转换 Promise 到 Observable。
import { defer } from 'rxjs';
const observable$ = defer(() => getPromise());
observable$
将是一个冷Observable。
它是一种冷Observable,因为生产者(Promise)是在Observable内部创建的。每个订阅者都会通过调用给定的Promise工厂函数来创建一个新的Promise。
这允许您创建一个observable$
,而无需立即创建和执行Promise,并且不与多个订阅者共享该Promise。
每个observable$
的订阅者实际上都会调用from(promiseFactory()).subscribe(subscriber)
。因此,每个订阅者都会创建并转换自己的新Promise为一个新的Observable,并将自己附加到这个新的Observable上。
3 Many Operators Accept Promises Directly
大多数RxJS操作符,如合并(例如merge
、concat
、forkJoin
、combineLatest
...)或转换Observable(例如switchMap
、mergeMap
、concatMap
、catchError
...)直接接受promises。如果您已经在使用其中之一,您不必先使用from
来包装promise(但为了创建一个冷Observable,您仍然可能需要使用defer
)。
forkJoin(getPromise(1), getPromise(2)).pipe(
switchMap(([v1, v2]) => v1.getPromise(v2))
)
查看文档或实现,以查看您正在使用的操作符是否接受ObservableInput
或SubscribableOrPromise
。
type ObservableInput<T> = SubscribableOrPromise<T> | ArrayLike<T> | Iterable<T>;
type SubscribableOrPromise<T> = Subscribable<T> | Subscribable<never> | PromiseLike<T> | InteropObservable<T>;
from
和defer
在一个例子中的区别:https://stackblitz.com/edit/rxjs-6rb7vf
const getPromise = val => new Promise(resolve => {
console.log('Promise created for', val);
setTimeout(() => resolve(`Promise Resolved: ${val}`), 5000);
});
const fromPromise$ = from(getPromise('FROM'));
const deferPromise$ = defer(() => getPromise('DEFER'));
fromPromise$.subscribe(console.log);
deferPromise$.subscribe(console.log);
defer
是许多应用程序依赖于可观察对象的冷启动和在订阅时触发数据获取的最常用运算符。尽管如此,对于某些用例,例如当您想要在某个初始化过程中创建一次Promise,然后通过可观察对象传播其值以供多次订阅,但不想为每个订阅者创建和执行Promise时,from
仍然是一个可行的选项。