【问题标题】:Recursive Function Will not go into return statement递归函数不会进入return语句
【发布时间】:2019-03-09 02:37:42
【问题描述】:

我正在使用 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))
    }
}

【问题讨论】:

  • 如果 fetchData 是你的 redux 操作之一,我假设它是,你必须用它调用 dispatch。 dispatch(fetchData())
  • @MaxBaldwin fetchData 不是 redux 操作之一。相反,这是
  • @MaxBaldwin 导出函数 GetImageFromSubSuccess(url){ return{ type: 'GET_IMAGE_FROM_SUB', imageUrl: url } }
  • thunk 应该支持 dispatch(fetchData())
  • 不应该是:return dispatch(GetImageFromSubSuccess(imageURL))

标签: javascript reactjs redux axios redux-thunk


【解决方案1】:

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

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

然后,定义递归承诺函数就变得更容易了。

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 或 typescript 以“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();
    }
}

类似的东西。上面的代码我没查,写出来说明思路。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-28
    • 2014-06-25
    • 2018-11-20
    • 2018-04-05
    • 2019-01-25
    • 1970-01-01
    • 2020-01-04
    • 2018-06-28
    相关资源
    最近更新 更多