1 直接执行/转换
使用from 直接将之前创建的 Promise 转换为 Observable。
import { from } from 'rxjs';
// getPromise() is called once, the promise is passed to the Observable
const observable$ = from(getPromise());
observable$ 将是一个hot Observable,它可以有效地将 Promises 值重播给订阅者。
它是一个热门的 Observable,因为生产者(在本例中为 Promise)是在 Observable 之外创建的。多个订阅者将共享同一个 Promise。如果内部 Promise 已解决,则 Observable 的新订阅者将立即获得其值。
2 每次订阅延迟执行
使用defer 和 Promise 工厂函数作为输入,以推迟 Promise 的创建和转换为 Observable。
import { defer } from 'rxjs';
// getPromise() is called every time someone subscribes to the observable$
const observable$ = defer(() => getPromise());
observable$ 将是一个冷 Observable。
这是一个冷的 Observable,因为生产者(Promise)是在 Observable 内部创建的。每个订阅者都会通过调用给定的 Promise 工厂函数来创建一个新的 Promise。
这允许您创建observable$,而无需立即创建并执行 Promise,也无需与多个订阅者共享此 Promise。
observable$ 的每个订阅者都有效地调用了from(promiseFactory()).subscribe(subscriber)。因此,每个订阅者都会创建自己的新 Promise 并将其转换为新的 Observable,并将自己附加到这个新的 Observable。
3 许多运营商直接接受承诺
大多数 RxJS 运算符组合(例如 merge、concat、forkJoin、combineLatest ...)或转换可观察对象(例如 switchMap、mergeMap、concatMap、catchError。 ..) 直接接受承诺。如果您仍然使用其中一个,则不必先使用 from 来包装承诺(但要创建 cold observable,您仍然可能必须使用 defer)。
// Execute two promises simultaneously
forkJoin(getPromise(1), getPromise(2)).pipe(
switchMap(([v1, v2]) => v1.getPromise(v2)) // map to nested Promise
)
检查documentation 或implementation 以查看您使用的运算符是否接受ObservableInput 或SubscribableOrPromise。
type ObservableInput<T> = SubscribableOrPromise<T> | ArrayLike<T> | Iterable<T>;
// Note the PromiseLike ----------------------------------------------------v
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);
});
// the execution of getPromise('FROM') starts here, when you create the promise inside from
const fromPromise$ = from(getPromise('FROM'));
const deferPromise$ = defer(() => getPromise('DEFER'));
fromPromise$.subscribe(console.log);
// the execution of getPromise('DEFER') starts here, when you subscribe to deferPromise$
deferPromise$.subscribe(console.log);