Угловое - возможное состояние гонки с - `publish (). RefCount ()`?

1

Я прочитал статью, в которой показан пример из 3 асинхронных подписок на HTTP-запрос.

@Component({
  selector: 'my-app',
  template: '
    <div>
      <p>{{ (person | async)?.id   }}</p>
      <p>{{ (person | async)?.title   }}</p>
      <p>{{ (person | async)?.body   }}</p>
    </div>
  ',
})
export class App {
  constructor(public http: Http) {
    this.person = this.http.get('https://jsonplaceholder.typicode.com/posts/1')
     .map(res => res.json())
  }
}

Я уже знаю, что здесь нет необходимости в async, и что ReplaySubject можно использовать и что есть много других решений, но это не то, что мне нужно.

Автор сказал, что:

Нынешнее решение, которое люди предлагают:

this.http.get('https://jsonplaceholder.typicode.com/posts/1').map(res => res.json()).share() (который является publish().refCount().)

Вопрос:

Но переосмысление about publish().refCount() - возможно ли (по какой-то причине):

  • Первый (person | async) выполнил запрос (refcount = 1), и ответ вернулся до (!) Двух последних (person | async) подписанных? - это вызовет другой HTTP-запрос (ы)? Я имею в виду - кто гарантирует, что 3 подписки будут доступны одновременно, чтобы все они имели один и тот же результат? есть ли возможность для состояния гонки? потому что я слышал, что refcount() зависит от состояния гонки.

  • Кроме того, когда он считается " refcount()>0 "? это значение, которое проверяется при вызове http или проверяется, когда ответ приходит?

Другими словами -

sub1 вызывает refcount()=1 (вызов http). Но между тем sub2 (вторая подписка):

  sub1 ———————A—————> http invoked    
   <—————————B———————response

Глядя на стадии A & B:

Когда будет refcount() будет 2? это на этапе A (до/в то время как http выполняется) или подписки на этапе B также будут считаться refcount()=2?

  • 0
    Возможно, publishReplay - это то, что вы ищете (см. Также stackoverflow.com/a/37756526/217408 )
  • 0
    @GünterZöchbauer GünterZöchbauer Привет, спасибо, да, я знаю, что могу использовать последнее значение (с помощью повторной публикации или темы воспроизведения / поведения) - Но я пытаюсь понять, есть ли здесь условие гонки + когда вычисляется пересчет.
Показать ещё 1 комментарий
Теги:
angular
rxjs5

1 ответ

1
Лучший ответ

Это действительно интересный вопрос. Но я думаю, что в этом фрагменте кода нет никаких условий гонки.

Дело в том, что вся подписка выполняется синхронно в шаблоне с помощью функции async. Это означает, что запрос будет запущен, когда первая подписка будет выполнена действительно, но в случае ответа сервера до того, как все остальные подписки будут выполнены (если это возможно), тогда основной поток будет занят, поэтому не будет запускать другой запрос когда придет следующая subscribe.

Вот небольшой пример, который я сделал, чтобы попытаться воспроизвести этот вариант использования.

const timer = Rx.Observable.of("value")
  .do(() => console.log("start request"))
  .delay(1)
  .do(() => console.log("end request"))
  .publish().refCount()

console.time("sub");
for (var i=0; i < 10; i++) {
  console.log("subscribe" + i)
  timer.subscribe()
}
console.timeEnd("sub")
<script src="https://unpkg.com/@reactivex/[email protected]/dist/global/Rx.js"></script>

Здесь я имитирую запрос, который отвечает сервером на 1 1ms, но все подписки занимают (по крайней мере, на моем компьютере) около 10 10ms для завершения. Поэтому вы можете сказать, что ответ приходит до того, как все подписки завершены.

Как вы можете видеть в журнале, запрос запускается только один раз :)

  • 0
    Я не понимаю тест. Время цикла не превышает 1 сек.
  • 0
    О, delay занимает несколько миллисекунд, а не секунд. Так что здесь это задержка в 1 1ms :)
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню