如何在React的另一个函数中为变量分配Ajax响应?

时间:2018-10-24 10:00:07

标签: javascript jquery node.js ajax reactjs

我有一个响应ajax的影片列表,然后我有一个具有另一个ajax调用的函数,另一个ajax调用返回了流派名称,因为第一个调用仅具有流派的ID,因此我将genreId及其名称,我在第一个ajax调用中将其分配给JSON,有点像将其分配给变量。我的问题是,由于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 :(得分:0)

有各种各样的解决方案可以解决您的问题。

最简单的方法是在second ajax call的回调中创建first ajax call。在第二个呼叫中,您将得到第一个ajax呼叫和第二个ajax呼叫的结果。然后进行转换并在第二个调用中设置状态。

其他选项(推荐的一种)是与依赖于Promises的AxiosFetch一起使用。 可以通过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"] 
});

答案 1 :(得分:0)

您可以尝试以下操作:

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})
    })
})

希望能帮助您!