直接执行/转换
使用from直接将先前创建的Promise转换为可观察对象。
import { from } from 'rxjs';
// getPromise() is called once, the promise is passed to the Observable
const observable$ = from(getPromise());
observable$将是一个热observable,有效地向订阅者重放Promises值。
它是一个热门可观察对象,因为生产者(在这个例子中是Promise)是在可观察对象之外创建的。多个订阅者将共享相同的承诺。如果内部Promise已经被解析,Observable的新订阅者将立即获得它的值。
2每个订阅的延迟执行
使用deferred和Promise工厂函数一起作为输入,将Promise的创建和转换延迟到可观察对象。
import { defer } from 'rxjs';
// getPromise() is called every time someone subscribes to the observable$
const observable$ = defer(() => getPromise());
observable$将是一个冷的observable。
它是一个冷可观察对象,因为生产者(Promise)是在可观察对象内部创建的。每个订阅者将通过调用给定的Promise工厂函数来创建一个新的Promise。
这允许你创建一个可观察对象$,而无需立即创建并执行Promise,也无需与多个订阅者共享这个Promise。
每个可观察对象$的订阅者有效地调用from(promiseFactory()).subscribe(subscriber)。所以每个订阅者创建并转换自己的新Promise到一个新的Observable,并将自己附加到这个新的Observable上。
许多运营商直接接受承诺
大多数组合(例如merge, concat, forkJoin, combineLatest…)或转换可观察对象(例如switchMap, mergeMap, concatMap, catchError…)的RxJS操作符直接接受promise。如果你正在使用它们中的一个,你不需要首先使用from来包装一个承诺(但要创建一个冷的可观察对象,你仍然可能需要使用defer)。
// Execute two promises simultaneously
forkJoin(getPromise(1), getPromise(2)).pipe(
switchMap(([v1, v2]) => v1.getPromise(v2)) // map to nested Promise
)
检查文档或实现,看看你使用的操作符是否接受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);
defer可能是大多数人都在寻找的操作符,因为许多应用程序依赖于Observables是冷的,并在订阅时触发数据获取。from在某些情况下仍然是一个可行的选择,例如,当你想在某个初始化过程中创建一个Promise,然后通过一个将被多次订阅的可观察对象传播它的值,但不想为每个订阅者再次创建和执行Promise。