Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/eclipse/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 角度2+;,在循环forEach中具有嵌套订阅的对象的订阅数组_Angular_Rxjs_Observable_Subscribe - Fatal编程技术网

Angular 角度2+;,在循环forEach中具有嵌套订阅的对象的订阅数组

Angular 角度2+;,在循环forEach中具有嵌套订阅的对象的订阅数组,angular,rxjs,observable,subscribe,Angular,Rxjs,Observable,Subscribe,我有两个不同的观测值。第一,获取项目列表。它返回json键之一为“fakturaId”的对象数组: “InvoicePreview”是“invoices”的一个键,因此在此之后,我有一个数组,我可以简单地使用*ngFor以HTML格式呈现所有项目的详细信息 有没有更好的方法来做同样的事情,但没有嵌套的订阅?如果一个应用程序有许多项,那么它的运行速度会非常慢。要将许多网络请求分组在一起并避免嵌套订阅(一种反模式),我建议您使用forkJoin和concatMap。forkJoin允许您对可观察对象

我有两个不同的观测值。第一,获取项目列表。它返回json键之一为“fakturaId”的对象数组:

“InvoicePreview”是“invoices”的一个键,因此在此之后,我有一个数组,我可以简单地使用*ngFor以HTML格式呈现所有项目的详细信息


有没有更好的方法来做同样的事情,但没有嵌套的订阅?如果一个应用程序有许多项,那么它的运行速度会非常慢。

要将许多网络请求分组在一起并避免嵌套订阅(一种反模式),我建议您使用
forkJoin
concatMap
。forkJoin允许您对可观察对象进行分组,
concatMap
是一个扁平化操作符

// getInvoices() {
//     this.invoiceService.getInvoiceForResidence().subscribe(res4 => {

//       // invoice list
//       this.invoices = res4;

//       // invoice details
//       this.invoices.forEach(inv => {
//         this.invoiceService.getInvoicePreview(inv.fakturaId).subscribe(res5 => {
//           inv.InvoicePreview = res5;
//         });
//       });
//     });
//   }

import { of, forkJoin, Observable } from 'rxjs'; 
import { tap, concatMap } from 'rxjs/operators'

let invoices = [];

function getInvoices() {
  // Mock your invoices
  const getInvoiceForResidence = of([{fakturaId: "invoice 1"}, {fakturaId: "invoice 2"}, {fakturaId: "invoice 3"}])
  const getInvoicePreview = (id: string) => of('preview from ' + id)

  return getInvoiceForResidence.pipe(
    tap((invoices) => invoices = invoices),
    concatMap((invoices ) => {
      const networkRequestsToMake: Observable<string>[] = invoices.map(invoice => getInvoicePreview(invoice.fakturaId))
      return forkJoin(...networkRequestsToMake)
    })
  )
}

getInvoices().subscribe(signal => {
  console.log(signal)
})


//getInvoices(){
//此.invoiceService.getInvoiceForResidence().subscribe(res4=>{
////发票清单
//此参数=res4;
////发票明细
//此.invoices.forEach(inv=>{
//this.invoiceService.getInvoicePreview(inv.fakturaId).subscribe(res5=>{
//inv.InvoicePreview=res5;
//         });
//       });
//     });
//   }
从“rxjs”导入{of,forkJoin,Observable};
从“rxjs/operators”导入{tap,concatMap}
让发票=[];
函数getInvoices(){
//伪造发票
const getInvoiceForResidence=of([{fakturaId:“发票1”},{fakturaId:“发票2”},{fakturaId:“发票3”}]))
const getInvoicePreview=(id:string)=>of('preview from'+id)
返回getInvoiceForResidence.pipe(
点击((发票)=>发票=发票),
concatMap((发票)=>{
const networkrequestToMake:Observable[]=invoices.map(invoice=>getinvoicespreview(invoice.fakturaId))
返回forkJoin(…NetworkRequestToMake)
})
)
}
getInvoices().订阅(信号=>{
控制台日志(信号)
})
请在此处复制并粘贴此代码:

这里有一些关于fork-join的信息

我建议您观看这段视频并全面阅读本文,以了解如何使用展平操作符


如果您需要更多帮助或说明,请告诉我。

使用发票或faktura…发送一组ID,而不是循环,然后一次捕获所有ID。解决此问题的方法很多。请看一个解决方案,我使用“invoice”,因为我更喜欢代码中的英语(这对其他开发人员更好,他们将来会使用我的代码),但我们的后台开发人员使用波兰语。这是如何不分离传输层的完美示例。如果你的barckend是中文的,你还会用吗??只是说说而已,谢谢!这工作做得很好。我已经阅读(并观看)了您链接的内容,但我对RxJS非常陌生,所以我需要一些时间来分析和理解它是如何工作的。我无法理解tap()在这段代码中的作用。我想这是为了调试,但你能解释一下吗?@Tribsk2,我们使用
tap
获取传入信号(我们的发票),并使用该数据设置名为
invoices
的全局变量。这相当于您的代码
This.invoices=res4@TribusK2,如果有帮助,请随意将此答案标记为正确!:D
getInvoicePreview(fakturaId: number) {
    return this.httpClient.get<InvoicePrev>(this.url + fakturaId);
  }
getInvoices() {
    this.invoiceService.getInvoiceForResidence().subscribe(res4 => {

      // invoice list
      this.invoices = res4;

      // invoice details
      this.invoices.forEach(inv => {
        this.invoiceService.getInvoicePreview(inv.fakturaId).subscribe(res5 => {
          inv.InvoicePreview = res5;
        });
      });
    });
  }
// getInvoices() {
//     this.invoiceService.getInvoiceForResidence().subscribe(res4 => {

//       // invoice list
//       this.invoices = res4;

//       // invoice details
//       this.invoices.forEach(inv => {
//         this.invoiceService.getInvoicePreview(inv.fakturaId).subscribe(res5 => {
//           inv.InvoicePreview = res5;
//         });
//       });
//     });
//   }

import { of, forkJoin, Observable } from 'rxjs'; 
import { tap, concatMap } from 'rxjs/operators'

let invoices = [];

function getInvoices() {
  // Mock your invoices
  const getInvoiceForResidence = of([{fakturaId: "invoice 1"}, {fakturaId: "invoice 2"}, {fakturaId: "invoice 3"}])
  const getInvoicePreview = (id: string) => of('preview from ' + id)

  return getInvoiceForResidence.pipe(
    tap((invoices) => invoices = invoices),
    concatMap((invoices ) => {
      const networkRequestsToMake: Observable<string>[] = invoices.map(invoice => getInvoicePreview(invoice.fakturaId))
      return forkJoin(...networkRequestsToMake)
    })
  )
}

getInvoices().subscribe(signal => {
  console.log(signal)
})