typescript - rxjs返回地图内事件的结果
问题描述
希望有人可以帮助我有一个可观察的,它在下面的 http 请求的映射中返回 base64 字符串
transform(url: string, asBase64: boolean): Observable<any> {
return this.http
.get(url, {responseType: 'blob'})
.pipe(map(val => {
if (!asBase64) {
return this.sanitizer.bypassSecurityTrustUrl(URL.createObjectURL(val))
}
let base64Data = null;
let reader = new FileReader();
reader.readAsDataURL(val);
reader.onloadend = () => {
base64Data = reader.result; // need to return this!
console.log(base64Data);
};
}));
}
问题是我需要有条件地返回结果 reader.onloadend = () => {
我想我需要将其转换为承诺并使用mergeMap?不知道怎么做。
更新
所以对此又进行了一次尝试。从mergeMap docs看起来这应该可以工作,调试我可以看到blob被传递给reader.readAsDataURL(data);
但从return reader.result;
不触发,看起来我失去了对reader
transform(url: string, asBase64: boolean): Observable<any> {
return this.http
.get(url, {responseType: 'blob'})
.pipe(map(val =>
<any>(asBase64 ? val : this.sanitizer.bypassSecurityTrustUrl(URL.createObjectURL(val)))
)).pipe(mergeMap(data => {
if (!asBase64) {
return of(data)
} else {
let reader = new FileReader();
let eventObservable = fromEvent(reader, 'onloadend').pipe(map(() => {
return reader.result;
}));
reader.readAsDataURL(data);
return eventObservable;
}
}));
}
解决方案
问题是 FileReader onLoadEnd 事件是异步的,所以它在 map 函数中不起作用。
解决问题的一种方法是使用 Promise 包装函数,使用from从 Promise 创建一个 observable ,然后使用switchMap运算符将您的 observable 映射到 Promise 中的新 observable。
现在,当您订阅生成的 observable 时,它将从 FileReader 发出结果。如果它拒绝,您可以使用 subscribe 方法的第二个参数获取错误。
import {from} from 'rxjs'
import {switchMap} from 'rxjs/operators'
transform(url: string, asBase64: boolean): Observable<any> {
return this.http
.get(url, {responseType: 'blob'})
.pipe(
switchMap(
val => from( // create the observable from a promise
new Promise((resolve, reject) => { //create a new Promise
if (!asBase64) {
resolve(this.sanitizer.bypassSecurityTrustUrl(URL.createObjectURL(val))) //resolve if base64
}
const reader = new FileReader();
reader.readAsDataURL(val);
reader.onloadend = () => resolve(reader.result); //resolve when it finishes to load the file
reader.onerror = () => reject(reader.error); //rejects if there was an error while reading the file
})
)
)
);
}
...
const file$ = transform(url, asBase64)
file$.subscribe(
(file) => console.log(file), // do stuff with the file here
(error) => console.log(error) // there was an error while reading the file
)
推荐阅读
- c# - 如何构造数据模型以绑定到具有 XML 列的 SQL 表
- python - 伪代码 Python 概念
- android - Kotlin - 如何将非空对象值设置为空?
- java - Combobox 上的 ZK 框架 onCreate 事件
- c# - 如何在 MacOS 中使用 C# 获取鼠标在屏幕上的位置?
- linux - 在 Linux 上执行自建的 ghostscript 二进制文件的问题
- python - 为实例设置类属性就是为所有实例设置它
- c# - 使用守护程序应用程序发送邮件
- windows - Windows Media 基础:IMFSinkWriter WriteSample API 返回错误 sampleduration is not set
- python - requests.exceptions.HTTPError: 415 Client Error Unsupported Media Type when using python zeep