Javascript 如何在高阶可观测值中返回外部可观测值而不是内部可观测值

Javascript 如何在高阶可观测值中返回外部可观测值而不是内部可观测值,javascript,angular,rxjs,observable,Javascript,Angular,Rxjs,Observable,让我们用以下代码澄清问题: this.rates$ = this._glbRateService.getRates(params); // 1 this.rates$.pipe( mergeMap(rates => { const priceByRates: Observable<any>[] = rates.map(rate => { const paramsRatingItemPr

让我们用以下代码澄清问题:

    this.rates$ = this._glbRateService.getRates(params); // 1
    this.rates$.pipe(
        mergeMap(rates => {
            const priceByRates: Observable<any>[] = rates.map(rate => {
                const paramsRatingItemProduct = {
                    idItem: product.idItem,
                    idRate: rate.idRate
                };
                return this._glbRatingItemProduct.getPrice(paramsRatingItemProduct); // 2
            });
            return priceByRates;
        })
    ).subscribe(response => {
        console.log(response); // 3
    });
this.rates$=this.\u glbRateService.getRates(params);//1.
这是一条.rates.pipe(
合并映射(速率=>{
const priceByRates:Observable[]=rates.map(rate=>{
常数paramsRatingItemProduct={
idItem:product.idItem,
idRate:rate.idRate
};
返回此项。_glbRatingItemProduct.getPrice(paramsRatingItemProduct);//2
});
退货价格;
})
).订阅(响应=>{
console.log(响应);//3
});
在该法典中:

  • 我从服务器获取费率
  • 对于每种价格,我都会得到价格(地图)
  • My console.log从内部订阅返回值(this.\u glbRatingItemProduct.getPr…)
  • 我想要的是对映射值和内部订阅进行逻辑处理

    大概是这样的:

    this.rates$ = this._glbRateService.getRates(params);
    this.rates$.pipe(
        mergeMap(rates => {
            const priceByRates: Observable<any>[] = rates.map(rate => {
                const paramsRatingItemProduct = {
                    idItem: product.idItem,
                    idRate: rate.idRate
                };
                return this._glbRatingItemProduct.getPrice(paramsRatingItemProduct);
                // WITH THE SUBSCRIPTION OF THIS RETURN I WANT TO MAKE LOGIC
                // WITH rates.map, and then return rates, NOT THE INNER SUBSCRIPTION
    
            });
            return priceByRates;
        })
    ).subscribe(response => {
        console.log(response);
    });
    
    this.rates$ = this._glbRateService.getRates(params);
    this.rates$.pipe(
      mergeMap(rates => rates.map(
        rate => this._glbRatingItemProduct.getPrice({
          idItem: product.idItem,
          idRate: rate.idRate
        })
      ),
      mergeAll()
    ).subscribe(console.log);
    
    this.rates$=this.\u glbRateService.getRates(参数);
    这是一条.rates.pipe(
    合并映射(速率=>{
    const priceByRates:Observable[]=rates.map(rate=>{
    常数paramsRatingItemProduct={
    idItem:product.idItem,
    idRate:rate.idRate
    };
    返回此。_glbRatingItemProduct.getPrice(paramsRatingItemProduct);
    //对于这份申报表的订阅,我想说明一下逻辑
    //使用rates.map,然后返回rates,而不是内部订阅
    });
    退货价格;
    })
    ).订阅(响应=>{
    控制台日志(响应);
    });
    
    您首先需要使用forkJoin执行内部可观察数组 然后使用数组运行映射函数

    mergeMap(rates => {
        const priceByRates: Observable<any>[] = rates.map(rate => {
            const paramsRatingItemProduct = {
                idItem: product.idItem,
                idRate: rate.idRate
            };
            return this._glbRatingItemProduct.getPrice(paramsRatingItemProduct);
    
        });
        return forkJoin(...priceByRates).pipe((values)=>values.map....your logic ));
    })
    
    mergeMap(速率=>{
    
    const priceByRates:Observable

    有时,分离映射逻辑并展平高阶观测值是有帮助的。这里应该更清楚一点,
    map()
    返回一个观测值数组,
    forkJoin()
    将所有这些观测值合并到一个流中

    this.rates$ = this._glbRateService.getRates(params);
    this.rates$.pipe(
      map(rates => rates.map(
        rate => this._glbRatingItemProduct.getPrice({
          idItem: product.idItem,
          idRate: rate.idRate
        })
      ),
      mergeMap(priceByRates => forkJoin(priceByRates))
    ).subscribe(console.log);
    
    另一方面,
    forkJoin()
    仅在所有源观测完成后发出。如果不需要将所有响应放在一起,则使用更简单的
    merge()
    将源流解耦。只需更改一行:

    mergeMap(priceByRates => merge(...priceByRates))
    

    需要记住的是,
    mergeMap
    需要返回一个流。它会将数组转换为一个值流。因此
    mergeMap(num=>[10,9,8,7,num])
    不会将
    num
    映射到数组中,而是创建一个新的流,一次一个地发出这些数字

    这就是为什么
    mergeMap(=>val:Observable[])
    只会一次发射一个可观测对象(作为高阶可观测对象)

    有了这些知识,您实际上可以在不使用上述静态合并功能的情况下将流更改为合并。这可能如下所示:

    this.rates$ = this._glbRateService.getRates(params);
    this.rates$.pipe(
        mergeMap(rates => {
            const priceByRates: Observable<any>[] = rates.map(rate => {
                const paramsRatingItemProduct = {
                    idItem: product.idItem,
                    idRate: rate.idRate
                };
                return this._glbRatingItemProduct.getPrice(paramsRatingItemProduct);
                // WITH THE SUBSCRIPTION OF THIS RETURN I WANT TO MAKE LOGIC
                // WITH rates.map, and then return rates, NOT THE INNER SUBSCRIPTION
    
            });
            return priceByRates;
        })
    ).subscribe(response => {
        console.log(response);
    });
    
    this.rates$ = this._glbRateService.getRates(params);
    this.rates$.pipe(
      mergeMap(rates => rates.map(
        rate => this._glbRatingItemProduct.getPrice({
          idItem: product.idItem,
          idRate: rate.idRate
        })
      ),
      mergeAll()
    ).subscribe(console.log);
    

    mergeAll()将在每个高阶可观察对象到达时接受它们,并订阅+合并它们的输出。

    这给了我:[Array(1),Array(1)],我如何使它成为:[{},{},{}…]您不需要任何rx操作员来完成此转换谢谢您的解释,更清楚,我很确定这也可以,但我使用了上面的解决方案,也谢谢您