#angular #rxjs #observable
Вопрос:
Пожалуйста, взгляните сюда
У меня есть наблюдаемое, на которое я подписываюсь два раза , один раз в обычном потоке, а другой в a forkJoin
, у меня есть pipe(share())
наблюдаемое, и все равно оно вызывает обещание внутри этого два раза, вместо того, чтобы вызывать его один раз и делиться значением.
Комментарии:
1. Конечно, @Дренай, я сделаю это в следующий раз. 🙂
Ответ №1:
Поведение, которое вы видите, частично объясняется следующей частью документов:
[поделиться] Возвращает новое наблюдаемое, которое многоадресно передает (совместно использует) исходное наблюдаемое. Пока есть хотя бы один Подписчик, этот Наблюдаемый будет подписываться и передавать данные. Когда все подписчики отпишутся, он отпишется от наблюдаемого источника.
Подписка является общей до тех пор, пока есть подписчики. Тем не менее, в вашем примере наблюдаемого использования of
, наблюдаемое излучает и завершается немедленно, что приводит к отмене подписки подписчиков. Когда происходит вторая подписка, других подписчиков нет, поэтому он снова запускает обещание.
Чтобы избежать этого, вы можете использовать shareReplay
для «воспроизведения» предыдущей рассылки новым подписчикам.
Вы можете увидеть такое поведение с помощью этого Стекблица.
Ответ №2:
Я не совсем уверен в том, что собираюсь сказать, но хорошо… это похоже new promise
на fn
создание побочного эффекта, который повторно запускает подписку fn2
. Использование обычного наблюдаемого в fn
, кажется, работает. Я не могу толком объяснить такое поведение, поэтому, если у кого-то есть что-то интересное, оставьте комментарий !
import { defer, forkJoin, from, of } from 'rxjs';
import { share } from 'rxjs/operators';
// Share isn't necessary here since you're subscribing only once to this observable
// let fn = defer(() => of([1, 2]));
let fn = defer(() => new Promise((x) => x(1)));
let fn2 = defer(() => from(
new Promise((x) => {
console.log('in');
x(1);
})
)).pipe(share());
fn2.subscribe((x) => console.log('[fn2] sub1'));
fn2.subscribe((x) => console.log('[fn2] sub2'));
forkJoin([fn]).subscribe((x) => {
// hypothesis : new promise is created since it's another context (subscribe are async)
// uncomment the first fn obs and there's no double 'in' in the console
fn2.subscribe((x) => console.log('sub'));
});
Комментарии:
1. ДА. Я тоже наблюдал это с fn по состоянию на(1). Именно в этом и заключается проблема. Любое замечание высоко ценится.