【问题标题】:How to assign an Ajax response to a variable in another function in React?如何将 Ajax 响应分配给 React 中另一个函数中的变量?
【发布时间】:2019-03-28 16:49:33
【问题描述】:

我有一个用电影列表响应的 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

}

【问题讨论】:

    标签: javascript jquery node.js ajax reactjs


    【解决方案1】:

    你可以试试这个:

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

    希望能帮到你!

    【讨论】:

      【解决方案2】:

      您的问题有多种解决方案。

      最简单的就是在first ajax call的回调中制作second ajax call。在第二次调用中,您将获得第一次 ajax 调用和第二次调用的结果。然后在第二次调用中进行转换并设置状态。

      其他选项(推荐的选项)是使用依赖 Promises 的 AxiosFetch。 Promise.all 可以规避 Promise:

      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"] 
      });

      【讨论】:

        猜你喜欢
        • 2016-12-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-04
        • 1970-01-01
        • 1970-01-01
        • 2017-10-20
        • 1970-01-01
        相关资源
        最近更新 更多