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

时间:2016-08-07 21:33:14

标签: reactjs redux

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

我怀疑我需要以某种方式搭载RSAA payload处理中的现有承诺链,但我不知道该怎么做。

以下是代码片段,其中注释了我需要执行promise resolve以返回此结果的行:

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 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

我设法解决了这个问题,所以我将回答我自己的问题......我只需要返回一个像这样的新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'));
        }
    })
});