有时获取 returns 未定义的数据

fetch returns undefined data sometimes

我使用 fetch 来获取信息,有时它能很好地显示所有内容,有时如果什么都不显示,则一切都是未定义的,有时它会很好地显示一些数据,但有些数据是未定义的。图片显示了我的问题:

这就是我的代码:

// fetch the movies from api

class Movie {

  constructor(id) {
    this.id = id;
    this.load();
  }
  finalize(json) {
    this.name = json.original_title;
    this.img = json.poster_path;
    this.link = name.replace(/[^a-zA-Z\s/ ]/g, "");
    var MyArray = {
      'name': `${this.name}`,
      'img': `${this.img}`,
      'link': `/movies/${this.link}.html`
    }
    console.log(MyArray)
  }

  load() {
    fetch(`https://api.themoviedb.org/3/movie/${this.id}?api_key=a913ee104db6b795d20852a9ed989036`)
      .then((res) => res.json())
      .then((json) => {
        this.finalize(json)
      })
      .catch(err => {
        console.error(err);
      });
  }

}

// The array of movies

const MyMovies = [
  new Movie(238),
  new Movie(899082),
  new Movie(899),
]

// show the movies in the page

function LoadMovies() {
  var table = document.querySelector('#movies')
  for (var i = 0; i < MyMovies.length; i++) {
    var item = MyMovies[i];
    var row = `<img id="img" src="${'https://image.tmdb.org/t/p/w185/' + item.img}" alt="${item.name}" class="thumb" onclick="location.href='${"movies/" + item.link + ".html"}'">`
    table.innerHTML += row
  }
}

您可以等到所有影片都初始化完毕:

// fetch the movies from api

class Movie {

  constructor(id) {
    this.id = id;
    this.isInitialized = this.load();
  }
  finalize(json) {
    this.name = json.original_title;
    this.img = json.poster_path;
    this.link = name.replace(/[^a-zA-Z\s/ ]/g, "");
    var MyArray = {
      'name': `${this.name}`,
      'img': `${this.img}`,
      'link': `/movies/${this.link}.html`
    }
    console.log(MyArray)
  }

  load() {
    return fetch(`https://api.themoviedb.org/3/movie/${this.id}?api_key=a913ee104db6b795d20852a9ed989036`)
      .then((res) => res.json())
      .then((json) => {
        this.finalize(json)
      })
      .catch(err => {
        console.error(err);
      });
  }

}

// The array of movies

const MyMovies = [
  new Movie(238),
  new Movie(899082),
  new Movie(899),
]

// show the movies in the page

async function LoadMovies() {
  var table = document.querySelector('#movies');
  await Promise.all(MyMovies.map(movie => movie.isInitialized));
  for (var i = 0; i < MyMovies.length; i++) {
    var item = MyMovies[i];
    var row = `<img id="img" src="${'https://image.tmdb.org/t/p/w185/' + item.img}" alt="${item.name}" class="thumb" onclick="location.href='${"movies/" + item.link + ".html"}'">`
    table.innerHTML += row
  }
}

LoadMovies();
<table id="movies">

</table>

构造函数不等待提取完成,因此您试图在提取信息之前使用所有 Movie 对象。没有办法等待 class 构造函数,因为它总是 returns 一个 class 实例,而不是承诺(参见 )。

不要在构造函数中调用 this.load(),而是在循环中调用。

class Movie {

  constructor(id) {
    this.id = id;
  }
  finalize(json) {
    this.name = json.original_title;
    this.img = json.poster_path;
    this.link = name.replace(/[^a-zA-Z\s/ ]/g, "");
    var MyArray = {
      'name': `${this.name}`,
      'img': `${this.img}`,
      'link': `/movies/${this.link}.html`
    }
    console.log(MyArray)
  }

  load() {
    fetch(`https://api.themoviedb.org/3/movie/${this.id}?api_key=a913ee104db6b795d20852a9ed989036`)
      .then((res) => res.json())
      .then((json) => {
        this.finalize(json)
      })
      .catch(err => {
        console.error(err);
      });
  }

}

// The array of movies

const MyMovies = [
  new Movie(238),
  new Movie(899082),
  new Movie(899),
]

// show the movies in the page

async function LoadMovies() {
  var table = document.querySelector('#movies')
  for (var i = 0; i < MyMovies.length; i++) {
    var item = MyMovies[i];
    await item.load();
    var row = `<img id="img" src="${'https://image.tmdb.org/t/p/w185/' + item.img}" alt="${item.name}" class="thumb" onclick="location.href='${"movies/" + item.link + ".html"}'">`
    table.innerHTML += row
  }
}