Оператор акций работает правильно? - PullRequest
0 голосов
/ 28 сентября 2018

Вот пример.Источник считается наполовину холодным, наполовину горячим:

const subject = new Subject()

const source = of(1, 2, 3).pipe(concat(subject))

const hot = source.pipe(
    share()
)

setTimeout(() => {
    hot.subscribe(val => console.log(`a: ${val}`))

    subject.next(6)
}, 1000)

subject.next(4)
subject.next(5)

Но вывод:

a: 1
a: 2
a: 3
a: 6

Считается ли это ожидаемым результатом или ошибкой?

Ответы [ 2 ]

0 голосов
/ 28 сентября 2018

Это ожидаемое поведение.Наблюдаемое является холодным в том смысле, что оно не начнет производить ничего, пока первый подписчик не подпишется на него, а затем он не подпишется на Subject и не выдаст значения от субъекта.Хронология примерно такая:

  1. subject создано
  2. source создано
  3. hot создано
  4. тайм-аутсозданный
  5. subject испускает 4
  6. subject испускает 5
  7. hot подписан на
  8. hot испускает 1
  9. hot испускает 2
  10. hot испускает 3
  11. hot подписывается на subject
  12. subject испускает 6
  13. hot испускает 6

Определение только наблюдаемого создает чертеж наблюдаемого, на самом деле это не Построен , прежде чем подписаться на наблюдаемую.Это также означает, что новая наблюдаемая создается (на основе этой схемы) каждый раз, когда вы подписываетесь на нее.

share гарантирует, что наблюдаемое создается только один раз, когда первая подписка подписывается на него.Любые последующие подписчики получат уже построенные наблюдаемые.Это разделено между ними.

Обратите внимание, что любые сигналы, испускаемые до подписки, не повторяются.После создания общая наблюдаемая становится горячей, поэтому новые подписчики будут получать только события, отправленные после их подписки.

EDIT :

Представьте, что у вас есть наблюдаемая, которая вызываетweb api каждые 10 секунд:

let getFromWebApi = interval(10 * 1000).pipe(
  mergeMap(_ => callWebApi())
)

Теперь представьте, что вы хотите получить эти результаты в пяти разных местах кода, вам нужно сделать следующее:

// Somewhere in your code
getFromWebApi.subscribe(response => /* Handle response */);

// Somewhere else in your code
getFromWebApi.subscribe(response => /* Handle response */);

// A third place in your code
getFromWebApi.subscribe(response => /* Handle response */);

// A fourth place in your code
getFromWebApi.subscribe(response => /* Handle response */);

// A fifth place in your code
getFromWebApi.subscribe(response => /* Handle response */);

Делать это впять разных мест создадут пять наблюдаемых, каждый из которых будет делать отдельный вызов веб-API каждые 10 секунд.Разве не было бы лучше, если бы вы делали только один звонок каждые 10 секунд, и все подписки разделили ответ?Вот что вы сделаете:

let getFromWebApi = interval(10 * 1000).pipe(
  mergeMap(_ => callWebApi()),
  share()
)

// Somewhere in your code
getFromWebApi.subscribe(response => /* Handle response */);
// ^^^ This will create the observable and start making web requests
// every 10 seconds

// The ones below will not create new observables,
// but receive the same observable as above. They will all receive
// responses every 10 seconds when the original observable returns.

// Somewhere else in your code
getFromWebApi.subscribe(response => /* Handle response */);

// A third place in your code
getFromWebApi.subscribe(response => /* Handle response */);

// A fourth place in your code
getFromWebApi.subscribe(response => /* Handle response */);

// A fifth place in your code
getFromWebApi.subscribe(response => /* Handle response */);

Если вы посмотрите на этот JSBin , вы увидите, что подписка на source пять раз создает пять «запросов»,Подписка на sharedSource создает только один «запрос»,

0 голосов
/ 28 сентября 2018

Да, это правильный результат, и вот почему:

  1. 'concat' подпишется на Subject только после завершения 'of (1,2,3)'.Но поскольку вы включаете hot.subscribe в setTimeout - subject.next (4) и 5 ​​не будут повторно отправлены в горячую подписку, поскольку они запускаются до того, как горячая подписка будет подписана в функции SetTimeout

  2. of имеет синхронизацию по умолчанию без задержки, поэтому вы сначала получаете 1,2,3 из 'of', а затем '6' из subject.next (6)

  3. Использование 'shareимеет смысл, если у вас есть некоторые задержки между выбросами и несколькими подписчиками.

...