如何有条件地订阅一个可观察的对象,等待响应并返回完整的结果?

时间:2019-05-16 07:55:31

标签: typescript rxjs twilio

我从Observable中得到一个Promise,就像这样(我使用的是严格的打字稿):

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)发出另一个请求。因此,在这种情况下,我必须取回 media url而不是 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 个答案:

答案 0 :(得分:3)

map更改为flatMap,并且不要在运算符内部进行subscribeflatMap将为您执行内部可观察的

          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