Как условно подписаться внутри наблюдаемой, дождаться ответа и вернуть полный результат? - PullRequest
1 голос
/ 16 мая 2019

У меня есть Observable из Promise, например, так (я использую строгий Typescript):

let foo: Subscription = from(channel.getMessages).pipe(flatMap((data: any) => data.items))

// then I subscribe to it like this
foo.subscribe((val: any) => console.log(val))

Мне нужно передать flatMap, потому что объект channel имеет свойство массива items, которое содержит все сообщения text . Это было бы довольно просто, однако некоторые сообщения имеют тип media , и в этих случаях я должен сделать еще один запрос с media.getContentUrl (который также является Promise). Так что в этом случае мне нужно вернуть url из media , а не text тело сообщения.

Пока я пытался сделать что-то вроде:

let foo = from(channel.getMessages)
            .pipe(
              flatMap(data => data.items), 
              map((item: any) => {
                if (item.type === 'media') {
                  return from(item.media.getContentUrl).subscribe((val: any) => val);
                }
                return item.body;
              })
            );

Возвращает item.body правильно, но выдает ошибку, когда сообщение типа media : TypeError: You provided 'function getContentUrl(): ... where stream was expected

Моя цель - создать заметку, в которой я получаю сообщения, но когда тип сообщения media Я отправляю другой запрос, жду его и собираю все вместе, так например, после получения данных мой массив будет выглядеть так:

messages = [
  'foo',
  'bar',
  'http://example.com/img1.jpg',
  'baz',
  'http://example.com/img2.jpg'
]

Основная проблема, с которой я сталкиваюсь в методе реактивного мышления, заключается в следующем: как настроить наблюдаемое, что может иметь другую наблюдаемую (или простой запрос) внутри, основанную на каком-то условии? Как бы вы сделали это в элегантной реактивной манере?

1 Ответ

3 голосов
/ 16 мая 2019

изменить map на flatMap и не subscribe внутри операторов, flatMap выполнит внутреннюю наблюдаемую для вас

          flatMap(data => data.items), 
          flatMap((item: any) => {
            return (item.type === 'media')? from(item.media.getContentUrl()):
            of(item.body);
          })

есть также оператор iif https://www.learnrxjs.io/operators/conditional/iif.html

но лично я придерживаюсь родного javascript

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...