微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

RxJS Observables数组以及要保留的其他数据

如何解决RxJS Observables数组以及要保留的其他数据

简短说明

如何通过为我需要在forkJoinpipe中使用的每个Observable传递一些数据来处理可观察变量数组(例如,在map中)?

const source = {animal: 'cat',fruit: 'apple',color: 'blue'}
const observables = Object.keys(source).map(key => [this.getDataFromApi(source[key]),key])

// resolve only observables[0][0],observables[0][1],observables[0][2] in magic way,// but preserve  observables[1][0],observables[1][1],observables[1][2] for future use in pipe&map
const processedobservable = forkJoin(observables).pipe( // ???
  map(items => items.map(item => 'this is ' + item[0] + '(' + item[1] + ')')),// this doesn't work
  map(items => items.join(','))
)

processedobservable.subscribe(text => console.log(text)) // subscribe only for test
// expected result: this is your cat (animal),this is your apple (fruit),this is your blue (color)

详细说明

我有一些“源”(项目的数组或对象)。我需要向API请求每个项,因此我得到了Observables数组。 接下来,我要处理所有接收到的数据,因此我使用forkJoin并在pipe和几个map中处理数据。

我无法直接处理订阅中的数据。

这是简单的示例:

const source = ['cat','apple','blue']
const observables = source.map(item => this.getDataFromApi(item))
const processedobservable = forkJoin(observables).pipe(
  map(items => items.map(item => 'this is ' + item)),map(items => items.join(','))
)
processedobservable.subscribe(text => console.log(text)) // test
// result: this is your cat,this is your apple,this is your blue

但是除了API请求的项目数据外,我还拥有在pipemap中处理期间必须使用的项目元数据。

这里是具有代表性来源的示例,但是这里我不使用项目的元数据(结果与上面相同)。我忽略了元数据:

const source = {animal: 'cat',color: 'blue'}
const observables = Object.keys(source).map(key => this.getDataFromApi(source[key]))
const processedobservable = forkJoin(observables).pipe(
  map(items => items.map(item => 'this is ' + item)),this is your blue

这里是具有代表性来源的示例,但是在这里我忽略了键和API调用,但是我处理了项目的元数据:

const source = {animal: 'cat',color: 'blue'}
const observables = Object.keys(source).map(key => of(key))
const processedobservable = forkJoin(observables).pipe(
  map(items => items.map(item => '(' + item + ')')),'))
)
processedobservable.subscribe(text => console.log(text)) // test
// result: (animal),(fruit),(color)

我想得到这个结果

// result: this is your cat (animal),this is your blue (color)

通过某种方式在pipemap中:

  map(items => items.map(item => 'this is ' + item.apiValue + '(' + item.key + ')')),

或:

  map(items => items.map(item => 'this is ' + item[0] + '(' + item[1] + ')')),

但是我不知道如何将可观察变量和元数据数组传递给forkJoin,其中一些具有元数据的可观察变量数组:

const observables = Object.keys(source).map(key => [this.getDataFromApi(source[key]),key])

也许我应该使用其他功能,例如flatMapswitchMap

其他信息

用于模拟API调用方法getDataFromApi

  getDataFromApi(item) {
    return of('your ' + item)
  }

解决方法

以下是如何实现的示例:

from(Object.entries(source))
 .pipe(
   mergeMap(([key,value]) => getFromApi(value).pipe(
     map(item => `this is ${item} (${key})`),// <= key is being closured
   )),toArray(),// <= transform stream to array 
   map(item => item.join()),)
 .subscribe(console.log);

尝试运行以下演示:

const { from,of } = rxjs;
const { map,switchMap,toArray } = rxjs.operators;

function getFromApi(item) {
  return of('your ' + item)
}

const source = { animal: "cat",fruit: "apple",color: "blue" };


from(Object.entries(source))
  .pipe(
    mergeMap(([key,value]) => getFromApi(value).pipe(
      map(item => `this is ${item} (${key})`),// <= key is being closured
    )),// <= transform stream to array 
    map(item => item.join()),)
  .subscribe(console.log);
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.6.2/rxjs.umd.min.js"></script>

,

您应将第一个map直接添加到创建各个可观察物的位置。

const source = { animal: "cat",color: "blue" };

const observables = Object.keys(source).map(key => getFromApi(source[key]).pipe(
  map(item => `this is ${item} (${key})`)
));

const processedObservable = forkJoin(observables).pipe(
  map(items => items.join(','))
);

processedObservable.subscribe(console.log);

https://stackblitz.com/edit/rxjs-4x7hbv?file=index.ts

,
function getDataFromApi(item) {
  return of('your ' + item)
}

const source = { animal: 'cat',fruit: 'apple',color: 'blue' };

from(Object.keys(source)).pipe(
  switchMap(key => forkJoin([getDataFromApi(source[key]),of(key)])),map(([data,key]) => `this is ${data} (${key})`),map(data => data.join(',')),).subscribe(console.log);

请参阅:https://stackblitz.com/edit/rxjs-1t4nlo?file=index.ts

,

尝试使用import { combineLatest } from 'rxjs'

 combineLatest(['cat','apple','blue'].map(item => this.getDataFromApi(item))).pipe(
    map(items => items.map(item => 'this is ' + item)),map(items => items.join(','))
  )
  .subscribe({
    next:(res) => console.log(res)
  })

Example in stackblitz

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。