使用 redux-api-middleware 处理图片/jpeg 内容

IT技术 reactjs redux
2021-05-23 02:09:43

我有一个用于检索内容RSAA(Redux 标准 API 调用操作)image/jpeg我见过的所有示例都处理 JSON 数据,因此我复制了该getJSON函数并实现了我自己的getImage函数来处理这种内容类型。我现在遇到的问题是这个 blob 需要转换为 base64,并且必须使用异步函数来完成。因此,我的 FSA 在此异步操作完成之前被触发。

我怀疑我需要在 RSAApayload处理中以某种方式捎带现有的Promise链,但我不确定如何做到这一点。

这是我需要执行Promiseresolve以返回此结果的行注释的代码片段

export function fetchSiteThumbnailImage(endpoint) {
    return {
        [CALL_API]: {
            endpoint,
            method: 'GET',
            headers: {
                'Accept': 'image/jpeg'
            },
            types: [
                LOAD_SITE_THUMBNAIL_REQUEST,
                {
                    type: LOAD_SITE_THUMBNAIL_SUCCESS,
                    payload: (action, state, res) => {
                        return getImage(res).then((blob) => {
                            const reader = new FileReader();
                            reader.readAsDataURL(blob); 
                            reader.onloadend = () => {
                                const base64data = reader.result;
                                return base64data; // this needs to "resolve" - how??
                            }
                        });
                    },
                    meta: (action, state, res) => {
                        return {
                            siteId,
                            endpoint
                        }
                    }
                },
                LOAD_SITE_THUMBNAIL_FAILURE
            ]
        }
    }
}

谢谢!

2个回答

你必须将你的FileReader逻辑包装成一个Promise

function readAsBase64(blob) {
    return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onload = () => {
            const base64data = reader.result;
            resolve(base64data);
        }
        reader.onerror = (err) => {
            reject(err);
        }
        reader.readAsDataURL(blob); 
    });
}

payload然后你的功能可以是

(action, state, res) => getImage(res).then(readAsBase64);

一些注意事项:

  • reader.onloadend在读取操作完成时调用(成功或失败),而reader.onload仅在成功完成和reader.onerror失败完成调用——您想将这两种情况分开。

  • 您应该在开始读取 blob 之前设置事件处理程序以避免竞争条件——所以放在reader.readAsDataURL最后。

我已经设法解决了这个问题,所以我会回答我自己的问题......我只需要像这样返回一个新的 Promise 对象:

return new Promise((resolve, reject) => {
    getImage(res).then((blob) => {
        const reader = new FileReader();
        reader.readAsDataURL(blob); 
        reader.onloadend = () => {
            const base64data = reader.result;
            resolve(base64data);
        }
        reader.onerror = () => {
            reject(Error('unable to process image/jpeg blob'));
        }
    })
});