Using redux-api-middleware to process image/jpeg content

我的未来我决定 提交于 2021-02-10 05:05:03

问题


I have an RSAA (Redux Standard API-calling Action) that I'm using to retrieve image/jpeg content. All the examples I've seen deal with JSON data so I copied the getJSON function and implemented my own getImage function to deal with this content type. The problem I'm now running into is that this blob needs to be converted to base64 and that has to be done using an async function. So, my FSA gets triggered before this async operation completes.

I suspect that I need to somehow piggyback on the existing promise chain in the RSAA payload processing but I'm not sure how to do this.

Here's the snippet of code with the line commented where I need to perform the promise resolve to return this result:

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
            ]
        }
    }
}

Thanks!


回答1:


You have to wrap your FileReader logic into a 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); 
    });
}

Your payload function can then just be

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

A couple of notes:

  • reader.onloadend gets called when the reading operation is completed (either in success or in failure), while reader.onload is called only on successful completion and reader.onerror only on failed completion — you want to separate the two cases.

  • You should set the event handlers before you start reading the blob to avoid race conditions — so put reader.readAsDataURL at the end.




回答2:


I have managed to solve this so I'll answer my own question... I just needed to return a new Promise object like this:

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'));
        }
    })
});                        


来源:https://stackoverflow.com/questions/38818782/using-redux-api-middleware-to-process-image-jpeg-content

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!