举个例子,
(下面的代码来自于项目),目的是读取用户选择的文件内容,然后构建请求进行发送
如果对于常规的formdata就不需要读取文件的内容,他会逐渐地读取和发送文件内容,但是我是想要完整地读取文件的内容,并且向后端发送。
这个需要使用promise或者obversable,但是对于还要进行分情况后续阻塞处理的话最好还是使用promise。
NzUploadFile是使用ng-zorro读取的文件列表,和常规的input选择的文件差不多。
下面的目的是 “阻塞”地读取一个文件数组中的图片,然后存储到一个组件变量中。
当执行
async fun1(){
await this.buildFileList();
console.log(this.chatFileList);
}
时,文件的内容就已经被全部读取了。
因为在网页中,filereader使用的是回调的方式,当文件读取完毕之后才会触发回调函数,file.readxxxx 只是启动一个文件地读取。而不是“阻塞”地读完。
代码:
fileList: NzUploadFile[] = [];
chatFileList: FileInChat[] = [];
export interface FileInChat{ fileName: string; fileType?: string; fileSize?: number; fileContent?: string;//bs64 }
isBase64Image(fileType: string): boolean {
return fileType.startsWith("image");
}
async buildFileList() {
const promises = this.fileList.map((file) => this.readFile(file));
await Promise.all(promises);
}
readFile(file: NzUploadFile): Promise<void> {
return new Promise<void>((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => {
const isImg = this.isBase64Image(file.type!);
let fileContent: string | ArrayBuffer | null;
if (isImg) {
fileContent = reader.result;
if (fileContent == null || fileContent instanceof ArrayBuffer) {
reject(new Error('File content error'));
return;
}
} else {
fileContent = '';
}
const afile: FileInChat = {
fileName: file.name,
fileType: file.type,
fileSize: file.size,
fileContent: fileContent,
};
this.chatFileList.push(afile);
resolve();
};
if (file) {
// @ts-ignore
reader.readAsDataURL(file);
}
});
}