использовать следующее значение горячего наблюдаемого, используя take и toPromise

avatar
cdaringe
8 апреля 2018 в 00:44
164
1
0

у меня есть горячая наблюдаемая, которую мне часто нужно запускать вручную. я использовал Subject для достижения этой цели. я хочу:

  • вызвать тему
  • захватить следующий вывод внутреннего наблюдаемого
  • запустить тему снова
  • захватить следующий вывод, снова

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

void async function () {
  var subject = new Rx.Subject()
  var inner = subject.combineLatest([subject]).share()
  // ^^ i have other observables here in addition to the subject
  // in my real use case.  also, i want the observable hot!
  var i = 1
  while (i <= 3) {
    console.log(`i is ${i}, print ${i} before "i is ${i + 1}"`)
    var singleValObs = inner.take(1) // prep to observe the next value
    subject.next(i) // trigger the next value
    var [val] = await singleValObs.toPromise()
    console.log(val)
    ++i
  }
}()

Я ожидаю, что 1, 2 и 3 будут зарегистрированы, но зарегистрирована только одна строка!

Я новичок в rx, но мне очень нравятся идеи, лежащие в его основе. спасибо за подсказки!

Источник
Randy Casburn
8 апреля 2018 в 03:23
0

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

Ответы (1)

avatar
Meir
8 апреля 2018 в 09:58
2

Ваше обещание создается после того, как субъект выдал значение, поэтому оно никогда не будет разрешено. Вы должны сначала создать обещание, затем вызвать next(i) и затем дождаться обещания, а именно:

var singleValObs = inner.take(1) // prep to observe the next value
var promise = singleValObs.toPromise();
subject.next(i) // trigger the next value
var [val] = await promise

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