Как назначить ответ Ajax на переменную в другой функции в React? - PullRequest
0 голосов
/ 24 октября 2018

У меня есть вызов ajax, который отвечает списком фильмов, а затем у меня есть другая функция с другим вызовом ajax, которая возвращает имена жанров, так как первый вызов имеет только идентификатор жанра, затем я связываюgenreId с его именем, и я назначаю его JSON при первом вызове ajax, что-то вроде присвоения переменной.Проблема, которая у меня есть, состоит в том, что, поскольку ajax является асинхронным, он всегда заканчивается неопределенным.Я не хочу делать его синхронным, так как это приведет к плохому взаимодействию с пользователем.

Первый вызов ajax

$.ajax({
        url: urlString,
        success: (searchResults) => {
            const results = searchResults.results

            var movieRows = [];

            results.forEach(movie => {
                movie.genres = this.getMovieGenres(movie.media_type, movie.genre_ids);

                const movieRow = <MovieRow key={movie.id} movie={movie}/>;
                movieRows.push(movieRow)
            });

            this.setState({rows: movieRows})

        },
        error: (xhr, status, err) => {
            console.log("Failed to fetch data...")
        }
    })

Функция, которую явызов со вторым вызовом ajax

getMovieGenres (mediaType ,movieGenreIds) {

    urlString = `https://api.themoviedb.org/3/genre/movie/list?api_key=${config.movieDBbApiKey}&language=en-US`ApiKey}&language=en-US`

    var genres = []

    $.ajax({
        url: urlString,
        async: true,
        crossDomain: true,
        method: "GET",
        success: searchResults => {
          for (let i = 0; i < movieGenreIds.length; i++) {
            for (let j = 0; j < searchResults.genres.length; i++){
              console.log(searchResults.genres[j].id)
              if (movieGenreIds[i] === searchResults.genres[j].id) {
                genres.push(searchResults.genres[j].name)
              }
            }
          }

        },
        error: (xhr, status, err) => {
            console.log("Failed to fetch data...")
        }
    })

  return genres

}

Ответы [ 2 ]

0 голосов
/ 24 октября 2018

вы можете попробовать это:

var promise = new Promise((resolve,reject)=> {
    return $.ajax({
        url: urlString,
        success: (searchResults) => {
            return resolve(searchResults.results)

        },
        error: (xhr, status, err) => {
            return reject("Failed to fetch data...")
        }
    })
})

функция, которая возвращает обещание

getMovieGenres (mediaType ,movieGenreIds) {

    urlString = `https://api.themoviedb.org/3/genre/movie/list?api_key=${config.movieDBbApiKey}&language=en-US`ApiKey}&language=en-US`

    var genres = []

    return new Promise((resolve,reject)=> {
        $.ajax({
            url: urlString,
            async: true,
            crossDomain: true,
            method: "GET",
            success: searchResults => {
                for (let i = 0; i < movieGenreIds.length; i++) {
                    for (let j = 0; j < searchResults.genres.length; i++){
                        console.log(searchResults.genres[j].id)
                        if (movieGenreIds[i] === searchResults.genres[j].id) {
                            genres.push(searchResults.genres[j].name)
                        }
                    }
                }

                return resolve(genres)

            },
            error: (xhr, status, err) => {
                return reject("Failed to fetch data...")
            }
        })
    }) 
}

наконец:

promise().then(results => {

    var movieRows = [];
    var tasks = []

    results.forEach(movie => {
        tasks.push(getMovieGenres(movie.media_type, movie.genre_ids))
    });

    Promise.all(tasks).then(output => {
        output.forEach(movie => {
            const movieRow = <MovieRow key={movie.id} movie={movie}/>;
            movieRows.push(movieRow)
        })

        this.setState({rows: movieRows})
    })
})

Надеюсь помочь вам!

0 голосов
/ 24 октября 2018

Существуют различные решения вашей проблемы.

Самое простое - сделать second ajax call в обратном вызове first ajax call.Во втором вызове вы получите как результаты первого вызова ajax, так и второго .Затем выполните преобразования и установите состояние во втором вызове.

Другие варианты (рекомендуемый вариант) - работа с Axios или Fetch, которые полагаются на обещания.Обещания можно избежать с Promise.all:

var p1 = Promise.resolve(3);
var p2 = 1337;
var p3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, "foo");
}); 

Promise.all([p1, p2, p3]).then(values => { 
  console.log(values); // [3, 1337, "foo"] 
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...