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(日志));
}
回复(回复);
}
我已将您最新的联合收割机简化为