1 Прямое выполнение / преобразование
Используйте from
для прямого преобразования ранее созданного обещания в наблюдаемое.
import { from } from 'rxjs';
// getPromise() will only be called once
const observable$ = from(getPromise());
observable$
будет горячей наблюдаемой, которая эффективно воспроизводит ценность обещаний для подписчиков.
Тело обещаний выполняется или уже было выполнено при создании наблюдаемого. Если внутреннее обещание было выполнено, новый подписчик на наблюдаемое немедленно получит его значение.
2 Отложенное выполнение при каждой подписке
Используйте defer
функцию фабрики обещаний в качестве входных данных, чтобы отложить создание и преобразование обещания в наблюдаемое.
import { defer } from 'rxjs';
// getPromise() will be called every time someone subscribes to the observable$
const observable$ = defer(() => getPromise());
observable$
будет холодной наблюдаемой .
Разница в from
том, что defer
ждет подписчика и только потом создает новое обещание, вызывая данную функцию фабрики обещаний. Это полезно, когда вы хотите создать наблюдаемое, но не хотите, чтобы внутреннее обещание выполнялось сразу. Внутреннее обещание будет выполнено только тогда, когда кто-то подпишется на наблюдаемое. Каждый подписчик также получит свою собственную новую наблюдаемую.
3 Многие операторы принимают обещания напрямую
Большинство RxJS операторов , которые сочетают в себе (например merge
, concat
, forkJoin
, combineLatest
...) или преобразовать Наблюдаемые (например switchMap
, mergeMap
, concatMap
, catchError
...) принимает обещания напрямую. В любом случае, если вы используете один из них, вам не нужно 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);
from
метод возвращает наблюдаемый, но он отправляет обещание в качестве значения для подписок. :(