Рекурсивная функция не перейдет в оператор return - PullRequest
0 голосов
/ 03 октября 2018

Я использую реагирование, редукс, редукс, thunk и axios, чтобы получить случайное изображение из reddit, используя их API.Если расширения изображения 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 голосов
/ 03 октября 2018

Проблема, затрудняющая выражение рекурсии, заключается в том, что ваш код возвращает функцию dispatch => ....Вам нужно определить отдельную асинхронную рекурсивную функцию для обработки ввода-вывода, а затем обернуть ее в 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.async / await делает код обещания похожим на обычный синхронный код, поэтому легко использовать все обычные методы, такие как итерация или рекурсия.Конечно, все, что написано с помощью async / await, может быть переписано с необработанными обещаниями (это то, что нужно сделать 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();
    }
}

Что-то подобное,Я не проверял приведенный выше код и написал его, чтобы проиллюстрировать идею.

...