Javascript RxJS:flatMap一个包含承诺结果的值数组

Javascript RxJS:flatMap一个包含承诺结果的值数组,javascript,rxjs,Javascript,Rxjs,我有一个类型温度,例如: type Temperature = { source: "Sensor A", value: number, } 以及这种类型的可观测发射阵列 temperatures$:$rxjs$Observable<Array<Temperature>> 但这不是很容易理解,必须有一种更简单的方法。它变得有点复杂的原因是你有一个可观测的发射温度阵列。我不知道你的具体用法,但是你应该考虑发射一系列的温度,即使用可观察的< /代码>。它将简化代码

我有一个类型温度,例如:

type Temperature = {
  source: "Sensor A",
  value: number,
}
以及这种类型的可观测发射阵列

temperatures$:$rxjs$Observable<Array<Temperature>>

但这不是很容易理解,必须有一种更简单的方法。

它变得有点复杂的原因是你有一个可观测的发射温度阵列。我不知道你的具体用法,但是你应该考虑发射一系列的温度,即使用<代码>可观察的< /代码>。它将简化代码

无论如何,假设您定义了用例,这段代码就可以了(我在这里使用TypeScript,但您可以轻松地将其转换为标准JS):

从'rxjs/Observable'导入{Observable};
导入“rxjs/add/observable/of”;
导入“rxjs/add/observable/forkJoin”;
导入'rxjs/add/operator/switchMap';
导入'rxjs/add/operator/map';
界面温度{
资料来源:string,
值:number,
}
接口结果{
成功:布尔,
消息:string
}
界面温度结果扩展了温度{
结果:结果
}
函数apiCall(温度:温度):可观察{
//执行API调用
}
函数addResultsToTemperatures(温度:可观测):可观测{
//对于每个发出的温度阵列,将其替换为。。。
返回温度.switchMap(
//…并行执行所有API调用的结果。。。
温度=>Observable.forkJoin(
温度.map(温度=>
apiCall(温度)
//…并将温度和结果合并,得到温度结果。。。
.map(结果=>({…温度,结果})
)
))
}

你完全正确!我在链的更上一层做了
ComibNetest()
,因为我需要它们在数组中的每个点上都有一些特定的元素来执行一些组合操作,但在这里之前,我能够大大简化代码。非常感谢你让我大开眼界!
type TemperatureWithResult = {
  ...Temperature,
  result: {
    success: boolean,
    message: string
  }
}

temperaturesWithResult$:$rxjs$Observable<Array<TemperatureWithResult>>
export default
  temperatures$: rxjs$Observable<Array<Temperature>>,
): rxjs$Observable<Array<TemperatureWithResult>> => {
  return temperatures$.flatMap(
    temperatures => {
      return new Promise(resolve => {
        const promisedResults = temperatures.map(temperatureObject => {

          const promisedResult = apiCall({
            temperature: temperatureObject.temperature,
          });

          return {
            ...temperatureObject,
            result: promisedResult, // this is a promise!
          };
        });

        const promises = spreadPromised.map(s => s.result);

        Promise.all(promises).then(results =>
          resolve(
            promisedResults.map((promisedResult, i) => ({
              ...promisedResult,
              result: {
                success: true, // to simplify
                message: results[i], // I update it with the actual result
              }
            })),
          ),
        );
      });
    },
  );
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import 'rxjs/add/observable/forkJoin';
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/operator/map';

interface Temperature {
  source: string,
  value: number,
}

interface Result {
  success: boolean,
  message: string
}

interface TemperatureWithResult extends Temperature {
  result: Result
}

function apiCall(temperature: Temperature): Observable<Result> {
  // perform API call
}

function addResultsToTemperatures(temperatures: Observable<Temperature[]>): Observable<TemperatureWithResult[]> {
  // for each array of temperatures emitted, replace them with...
  return temperatures.switchMap(
    // ...the result of doing all the API calls in parallel...
    temperatures => Observable.forkJoin(
      temperatures.map(temperature => 
        apiCall(temperature)
          // ...and merging temperature and result to yield a TemperatureWithResult...
          .map(result => ({ ...temperature, result })
      )
    ))
}