Javascript Can';t从CombineTest获取数据-角度

Javascript Can';t从CombineTest获取数据-角度,javascript,angular,typescript,rxjs,resolver,Javascript,Angular,Typescript,Rxjs,Resolver,我正在尝试将文件包括在一篇文章的日志中。我做错了什么?当我尝试pipecombinelatetest的结果时,数据不会在链中稍后出现。整个代码用于数据解析器服务 return this.API.getPost(route.params.id).pipe( switchMap((response: any) => { if (response["logs"]) { response["logs"].map(logs => { if (logs["

我正在尝试将文件包括在一篇文章的日志中。我做错了什么?当我尝试
pipe
combinelatetest的结果时,数据不会在链中稍后出现。整个代码用于数据解析器服务

return this.API.getPost(route.params.id).pipe(
  switchMap((response: any) => {
    if (response["logs"]) {
      response["logs"].map(logs => {
        if (logs["files"]) {
          return combineLatest(
            ...logs["files"].map(file=>
              this.API.getFile(file.id)
            )
          ).pipe(
            // Not getting any files from this.API.getFile(file.id)
            map(files =>
              files.map(file => ({
                url: this.sanitizer.bypassSecurityTrustResourceUrl(
                  window.URL.createObjectURL(file)
                )
              }))
            )
          ),
            map(files => {
              logs["files"] = files;
              return response;
            });
        }
      });
    }
    return of(response);
  })
)
请注意,
combinelateest
在每个可观察对象至少发出一个值之前,不会发出初始值。这与
withLatestFrom
的行为相同,可能是一个陷阱,因为不会有输出,也不会有错误,但一个(或多个)内部观察值可能无法按预期运行,或者订阅延迟

可能是您的API调用之一:

this.API.getFile(file.id)
返回错误或从未完成

这是直截了当的


更新: 在提到使用RxJs 6之后,您需要知道
CombineTest
需要一个数组作为参数

所以你应该考虑改为:

return combineLatest(
  logs["files"].map(
    file => this.API.getFile(file.id);
  ),
);
请注意,
combinelateest
在每个可观察对象至少发出一个值之前,不会发出初始值。这与
withLatestFrom
的行为相同,可能是一个陷阱,因为不会有输出,也不会有错误,但一个(或多个)内部观察值可能无法按预期运行,或者订阅延迟

可能是您的API调用之一:

this.API.getFile(file.id)
返回错误或从未完成

这是直截了当的


更新: 在提到使用RxJs 6之后,您需要知道
CombineTest
需要一个数组作为参数

所以你应该考虑改为:

return combineLatest(
  logs["files"].map(
    file => this.API.getFile(file.id);
  ),
);
你的问题 您没有将可观察的
组合相关测试
返回到您的
开关映射

switchMap
中的
if
块中,您只是在创建一个未使用的可观察对象映射

以一种非常简单的方式,您目前正在这样做:

switchMap(响应=>
如果(响应[“日志”]){
响应[“日志”].map(日志=>of(日志));
}
回复(回复);
}
我已将最新的合并简化为
of
以演示问题。当
if
条件通过时,该块将创建一个新数组,然后立即忽略该数组。这意味着无论您的if条件如何,
switchMap
将始终调用
of(响应)
。您的
CombineTest
阵列将永远不会运行

解决办法 您需要从
if
块返回某种类型的可观察对象。如果您考虑正在创建的数据类型,它是一个可观察对象数组。因此,您需要一个
forkJoin
来运行一个可观察对象数组,并返回一个
switchMap
可以切换到的可观察对象

返回this.API.getPost(this.route.params.id).pipe(
开关映射((响应:任意)=>{
如果(响应[“日志”]){
返回forkJoin(响应[“日志”].map(日志=>{
如果(日志[“文件”]){
返回组合测试(
…日志[“文件”].map(文件=>
this.API.getFile(file.id)
)
).烟斗(
映射(文件=>
file.map(文件=>({
url:this.sanitizer.bypassSecurityTrustResourceUrl(
window.URL.createObjectURL(文件)
)
}))
)
),
//不知道这是什么???
映射(文件=>{
日志[“文件”]=文件;
返回响应;
});
}
}));
}
回复(回复);
})
)
此外,我不确定我评论的
地图的目的是什么-它目前没有任何用途,甚至可能导致编译问题

演示:

此演示对您的问题进行了过于简单的抽象。“不工作”版本创建了一个不返回的可观察对象映射。“工作”版本切换到
forkJoin
并返回该值。在这两种情况下,如果
块为真,则保护
的条件为真

优化可观察的创造 我认为内部可观察物的创建可以简化并变得更安全

当您可以直接使用
forkJoin
时,在
forkJoin
中包装一个
combinelatetest
数组似乎有点多余

为了让它更清楚,我将把数组映射与可观察的创建分开。这也将帮助您避免出现错误,因为在
combinelateest
forkJoin
中会出现一个空数组

//在“if”块内
//展平文件
常量文件=响应[“日志”]
.filter(log=>!!log.files)
.map(log=>log.files)
.flat();
如果(files.length>0){
const observables=files.map(file=>this.API.getFile(file.id));
返回分叉连接(可观察)。管道(
映射(文件=>{
file.map(文件=>({
url:this.sanitizer.bypassSecurityTrustResourceUrl(
window.URL.createObjectURL(文件)
)
}))
})
);
}
这使用了
.flat()
数组函数,该函数采用多维数组,如:

[
 [1,2,3],
 [4,5,6]
]
并将其展平为:

[ 1,2,3,4,5,6 ]
如果您需要IE支持,并且没有polyfill,您可以在此处使用其他选项:

我还建议您创建一些接口并使用强类型。如果您仅仅依赖良好的变量命名(当然,我们从来没有给变量起过不好的名字),您很快就会迷失方向。

您的问题 您没有将可观察的
组合相关测试
返回到您的
开关映射

switchMap
中的
if
块中,您只是在创建一个未使用的可观察对象映射

以一种非常简单的方式,您目前正在这样做:

switchMap(响应=>
如果(响应[“日志”]){
响应[“日志”].map(日志=>of(日志));
}
回复(回复);
}
我已将您最新的联合收割机简化为