递归函数不会进入return语句

时间:2018-10-03 19:18:50

标签: javascript reactjs redux axios redux-thunk

我正在使用react,redux,redux thunk和axios使用其api从reddit获取随机图像。如果图像扩展名是gifv或域不在范围内,我想递归调用该函数。但是,当我递归调用该函数时,它将不会进入return语句。我以为这与诺言有关,但我不确定。

export function fetchData(){

    let ran = randomNumber();
    return(dispatch) => {
        return axios.get(`https://www.reddit.com/r/${subreddits[ran]}/random.json`)
        .then((res) => {
            let post = res.data[0].data.children[0].data;
            if(post.domain === 'i.redd.it' || post.domain === 'i.imgur.com') {
                let imageURL = post.url;
                if(imageURL.split()[3] !== 'gifv'){
                    dispatch(GetImageFromSubSuccess(imageURL))
                }else{
                    return fetchData();
                }
            }else {
                return fetchData();
            }
        }).catch(err => console.log(err))
    }
}

1 个答案:

答案 0 :(得分:0)

难以表达递归的问题是您的代码返回了dispatch => ...函数。您需要定义单独的异步递归函数来处理I / O,然后将其包装到dispatch => whatever

export function fetchData(){
    return(dispatch) => (
        doRecursiveIO().then( imageURL => dispatch( GetImageFromSubSuccess(imageURL) ) );
    )
}

然后,定义递归promise函数变得更加容易。

function doRecursiveIO(){
    let ran = randomNumber();

    return axios.get(`https://www.reddit.com/r/${subreddits[ran]}/random.json`)
        .then( res => {
            let post = res.data[0].data.children[0].data;

            if(post.domain === 'i.redd.it' || post.domain === 'i.imgur.com') {
                let imageURL = post.url;
                if(imageURL.split()[3] !== 'gifv'){
                    return imageURL;
                }else{
                    return doRecursiveIO();
                }
            }else {
                return doRecursiveIO();
            }
        });
}

如果要使用async/await,则可以通过非常简单的方式将递归与异步I / O结合使用。 async / await使Promise代码看起来像是常规同步代码,因此可以轻松使用所有常规技术,例如迭代或递归。当然,用async / await编写的任何内容都可以用原始的Promise重写(这就是babel或打字稿将“ es5”或“ es6”作为目标时所做的事情。)

async function doRecursiveIO(){
    let ran = randomNumber(),
        res = await axios.get(`https://www.reddit.com/r/${subreddits[ran]}/random.json`);

    let post = res.data[0].data.children[0].data;

    if(post.domain === 'i.redd.it' || post.domain === 'i.imgur.com') {
        let imageURL = post.url;
        if(imageURL.split()[3] !== 'gifv'){
            return imageURL;
        }else{
            return await doRecursiveIO();
        }
    }else {
        return await doRecursiveIO();
    }
}

类似的东西。我没有检查上面的代码并编写了代码来说明这个想法。