FileReader的使用机会很多,但是它是异步的,因此很容易出现回调地狱。

我们可以使用async/await特性,它允许我们以同步的方式调用异步代码。

封装成方法

export async function readTextFile(file: File) {
    const reader = new FileReader();
    reader.readAsText(file);
    return new Promise((resolve, reject) => {
        reader.onload = () => resolve(reader.result);
        reader.onerror = () => reject(reader.error);
    });
}

export async function readBinaryFile(file: File) {
    const reader = new FileReader();
    reader.readAsArrayBuffer(file);
    return new Promise((resolve, reject) => {
        reader.onload = () => resolve(reader.result);
        reader.onerror = () => reject(reader.error);
    });
}

export async function readAsText(file: File) {
    const reader = new FileReader();
    reader.readAsText(file);
    return new Promise((resolve, reject) => {
        reader.onload = () => resolve(reader.result);
        reader.onerror = () => reject(reader.error);
    });
}

使用方法:

(async()=> {
    const buffer1 = await readTextFile(file);
    const buffer2 = await readBinaryFile(file);
    const buffer3 = await readAsText(file);
})();

Javascript封装成一个class

class FileReaderEx extends FileReader{
    constructor(){
        super();
    }

    #readAs(blob, ctx){
        return new Promise((res, rej)=>{
            super.addEventListener("load", ({target}) => res(target.result));
            super.addEventListener("error", ({target}) => rej(target.error));
            super[ctx](blob);
        });
    }

    readAsArrayBuffer(blob){
        return this.#readAs(blob, "readAsArrayBuffer");
    }

    readAsDataURL(blob){
        return this.#readAs(blob, "readAsDataURL");
    }

    readAsText(blob){
        return this.#readAs(blob, "readAsText");
    }
}

使用方法:

(async()=>{
    const buffer1 = await new FileReaderEx().readAsArrayBuffer(blob1);
    const buffer2 = await new FileReaderEx().readAsDataURL(blob2);
    const buffer3 = await new FileReaderEx().readAsText(blob3);
})();

TypeScript封装成一个class

export class FileReaderEx extends FileReader {
    constructor() {
        super();
    }

    private readAs(blob: Blob, ctx: 'readAsArrayBuffer' | 'readAsDataURL' | 'readAsText') {
        return new Promise((res, rej) => {
            super.addEventListener("load", ({target}) => res(target?.result));
            super.addEventListener("error", ({target}) => rej(target?.error));

            super[ctx](blob);
        });
    }

    readAsArrayBuffer(blob: Blob) {
        return this.readAs(blob, "readAsArrayBuffer");
    }

    readAsDataURL(blob: Blob) {
        return this.readAs(blob, "readAsDataURL");
    }

    readAsText(blob: Blob) {
        return this.readAs(blob, "readAsText");
    }
}

使用方法:

(async()=>{
    const buffer1 = await new FileReaderEx().readAsArrayBuffer(blob1);
    const buffer2 = await new FileReaderEx().readAsDataURL(blob2);
    const buffer3 = await new FileReaderEx().readAsText(blob3);
})();

TypeScript基于泛型

/**
 * @description 同步调用包装
 * @param promise 需要被调用的异步方法
 */
async function asyncWrap<T = any>(promise: Promise<T>): Promise<T | null> {
    try {
        return await promise;
    } catch (err) {
        return null;
    }
}

export async function fileReaderWrap<T = any>(blob: Blob, ctx: 'readAsArrayBuffer' | 'readAsDataURL' | 'readAsText'): Promise<any> {
    const reader = new FileReader();
    reader[ctx](blob);
    return new Promise((resolve, reject) => {
        reader.onload = () => resolve(reader.result);
        reader.onerror = () => reject(reader.error);
    });
}

使用方法:

(async()=>{
    const buffer1 = await asyncWrap<ArrayBuffer>(fileReaderWrap<ArrayBuffer>(file, 'readAsArrayBuffer'));
    const buffer2 = await asyncWrap<ArrayBuffer>(fileReaderWrap<ArrayBuffer>(file, 'readAsDataURL'));
    const buffer3 = await asyncWrap<ArrayBuffer>(fileReaderWrap<ArrayBuffer>(file, 'readAsText'));
})();

到此这篇关于详解Javascript如何通过async/await优雅地使用FileReader的文章就介绍到这了,更多相关Javascript async/await使用FileReader内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部