React Redux thunk:调度到商店需要太长时间

时间:2018-02-14 15:11:39

标签: reactjs react-native redux react-redux redux-thunk

我正在尝试获取所有图像(userPics等)并将Base64字符串存储在我的Redux存储中(以便我可以脱机使用它们)。因此,我在渲染之前在应用程序的开头加载/获取这些图像。我使用redux-thunk,所以我可以调度一个动作(获取,返回一个Promise),然后(.then())调度来存储它们。

然而,并非所有图像都在渲染之前存储(尽管我非常确定我声明了Promise(s))。这是我的缓存(用于图像)reducer(包括获取操作):

const initialState = {
  images: [],
}


//Reducer
export default (state = initialState, action) => {
    let index, images;
    images = state.images.slice();
    index = images.findIndex(x => x.url===action.url);
    switch (action.type){
        //Store images
        case STORE_IMAGE:
            if( index === -1){
                images.push({url:action.url,  
                            img: action.img, 
                            width: action.width, 
                            height: action.height});
            }else{
                images[index] = {url:action.url, 
                                img: action.img, 
                                width: action.width, 
                                height: action.height};
            }
            return {
                ...state,
                images: images
            }

        default: 
            return state
    }
}

//ARE THERE SIDE EFFECTS?
export const storeImage = (url, img, width, height) => {
    return dispatch => 
        dispatch({
            type: STORE_IMAGE,
            url: url,
            img: img,
            width: width,
            height: height
        });

}

//Fetch, returns Promise (used to render when resolved)
export const cacheImage = (url) => {
    return dispatch => new Promise((resolve, reject) => {
        //test if images is already fetched
        let images = store.getState().cache.images;
        let index = images.findIndex(x => x.url===url);
        if(index === -1){
            let mimeType = mime.lookup(url.split("?")[0]);
            RNFetchBlob.fetch('GET', url)
              .then((response) => {

                let base64Str = response.data;
                var imageBase64 = 'data:'+mimeType+';base64,'+base64Str;
                // Get resolution
                Image.getSize(imageBase64, (width, height) => {
                    // Store base64 image
                    dispatch(storeImage(url, imageBase64, width, height));
                    resolve(imageBase64);
                });

             }).catch((error) => {
               // error handling
               reject(error);
            });
        }else{
            //already fetched
            resolve(images[index].img);
        }
    });
}

如果我用足够的时间包含setTimeout()来解析Promise(在Images.getSize中),则所有图像都会在渲染之前存储。这让我很奇怪,因为我认为内部dispatch(storeImage)是一个没有副作用的函数(至少应该是这样)?!我无法做出另一个承诺,对吗?

1 个答案:

答案 0 :(得分:0)

我发现代码中没有错误:我希望Image.getSize成为罪魁祸首。如果没有调用回调的原因,请检查实现。

说:如果Base64是将图像存储在本地缓存中的最佳格式,我建议你做一些调查。