我正在使用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
]
}
}
}
谢谢!
答案 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'));
}
})
});