将base64数据保存到变量中

时间:2019-02-19 12:37:02

标签: javascript reactjs base64

我在这里看到了几个示例,并根据这些示例准备了解决方案。但是我仍然得到Promise __proto__: Promise [[PromiseStatus]]: "pending [[PromiseValue]]: undefined 我试图将我的base 64数据存储到我的base64变量中。请让我知道我的代码和有效的解决方案出了什么问题。

以下是我的尝试:

import React, { Component } from 'react'
import { DropzoneArea, DropzoneDialog } from 'material-ui-dropzone'
import Button from '@material-ui/core/Button';


async function getBaseData(selectedFile) {
    let base64;
    var fileToLoad = selectedFile[0];
    base64 = await getBase64(fileToLoad);
    return base64; //This returns me PromiseStatus Pending
}

function getBase64(file) {
    return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = () => resolve(reader.result);
        reader.onerror = error => reject(error);
        return Promise.resolve(reader.result)
    });
}

export class ImageUploader extends Component {
    constructor(props) {
        super(props);
        this.state = {
            files: [],
            image: null,
        };
    }
    handleImageChange(files) {
        const { imageCallback } = this.props
        imageCallback(getBaseData(files)); // By this callback i am trying to pass my base64 string to other component
    }
    render() {
        return (
            <DropzoneArea
                acceptedFiles={['image/*']}
                filesLimit={1}
                maxFileSize={10000000}
                //showPreviews={false}
                onChange={this.handleImageChange.bind(this)}
            />
        )
    }
}

3 个答案:

答案 0 :(得分:2)

您的问题是您如何管理Promise。您不需要以documentation says的形式从Promise中退回任何东西,否则它将立即解决。

在这种情况下,当您这样做:

function getBase64(file) {
    return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = () => resolve(reader.result);
        reader.onerror = error => reject(error);
        return Promise.resolve(reader.result) // <--- this is wrong.
    });
}

它将解析为未定义的Promise.resolve(reader.result),因为也许它没有完成,也许而且也许您可以获得准确的结果,但是幸运的是reader在此之前实际上已经解析了return(比赛条件)

从根本上说,要使其生效,您需要使用承诺的resolverrejecter,以便它可以解决/拒绝。

编辑:我注意到您在设置回调之前还调用了reader函数,然后读取文件,添加了回调,然后未调用这些回调。

只需将您的代码更改为此:

function getBase64(file) {
    return new Promise((resolve, reject) => {
        const reader = new FileReader();

        //set the callbacks before reading the object
        reader.onload = () => resolve(reader.result); 
        reader.onerror = error => reject(error);

        reader.readAsDataURL(file);
    });
}

答案 1 :(得分:1)

问题是getBaseData是一个异步函数,但是您仍然需要等待它解决。

尝试“等待”,就像这样:

handleImageChange(files) {
            const { imageCallback } = this.props;
            async function wrap(){
               const result = await getBaseData(files); //result should be a value here and not promise
               imageCallback(result);
            }
            wrap(); // call the async function which will await the getBaseData and use your callback

        }

答案 2 :(得分:0)

这里有两个问题:Promise的创建是不正确的,并且您未按应有的方式处理已解决的Promise。像其他答案所建议的那样,不需要asyncawait

Promise的创建:

function getBaseData(selectedFiles) {
    var fileToLoad = selectedFiles[0];
    return getBase64(fileToLoad);
}

function getBase64(file) {
    return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onload = () => resolve(reader.result); 
        reader.onerror = error => reject(error);
        reader.readAsDataURL(file);
    });
}

解决Promise

handleImageChange(files) {
    const { imageCallback } = this.props
    getBaseData(files).then(imageCallback);
}