Promise.all()不能总是得到解决-编辑以添加两个函数的代码

时间:2018-08-08 11:07:09

标签: javascript arrays reactjs promise

我正在使用以下代码更新状态,但是Promise.all()数组在调用最终函数之前并不总是能够解决。有时,整个数组都会被填充,但通常不是。

我正在将Promise.all()数组记录到控制台中,以便了解发生了什么。真正奇怪的是状态总是正确更新,但是调用数组中的各个元素通常会返回“ undefined”。我需要使用单个元素创建一个新的数组以供以后显示,这就是为什么我要访问它们。

请帮助我弄清楚更新完成后如何访问数组,或者是一种更好的处理整个过程的方法。

class X {
  componentDidMount() {
    const numTiles = 3;

    for (let i = 0; i < numTiles; i++) {
      Promise.all([
        this.fetchSong(), // returns JSON from SQLite DB
        this.fetchArtists(),  // returns JSON from SQLite DB
      ]) 
        .then(values => {
          this.testing(values);
        });
    }
  }

  testing(arr) {
    console.log("arr: ", arr);
    console.log("arr[0]: ", arr[0]);
    console.log("arr[0].id: ", arr[0].id);
    console.log("arr[0].name: ", arr[0].name);
    console.log("arr[0].artist: ", arr[0].artist);
    console.log("arr[1]: ", arr[1]);
    console.log("arr[1][0]: ", arr[1][0]);
    console.log("arr[1][1]: ", arr[1][1]);
    console.log("arr[1][0].artist: ", arr[1][0].artist);
    console.log("arr[1][1].artist: ", arr[1][1].artist);
  }
}

编辑:添加了fetchSong()和fetchArtists()的代码。

fetchSong() {
    let id = Math.floor(Math.random() * 2000) + 1;  // get random number for id
    return new Promise((resolve, reject) => {
      Bingo.getSong(id).then(song => {
        resolve(song);
      });
    });
  }

  fetchArtists() {
    return new Promise((resolve, reject) => {
      let arr = [];
      for (let j = 0; j < 2; j++) {
        let id = Math.floor(Math.random() * 10) + 1;
        Bingo.getArtist(id).then(artist => {
          arr.push(artist);
        });
        resolve(arr);
      };
    });
  }

下面的控制台屏幕截图显示Promise.all()数组已被填充,但数组元素仍然丢失。

Console screenshot

1 个答案:

答案 0 :(得分:1)

问题出在fetchArtists的实现中,该实现在任何单艺术家获取承诺都得到解决之前就解决了。

我也简化了fetchSong,但是fetchArtists的要点是您存储将解决单个艺术家的承诺,然后等待所有艺术家解决。没有理由在其中添加.then(),因为您知道,Promise.all()会使用一系列已解析的值进行解析。

fetchSong() {
  const id = Math.floor(Math.random() * 2000) + 1;
  return Bingo.getSong(id);
}

fetchArtists() {
  const fetchPromises = [];
  for (let j = 0; j < 2; j++) {
    const id = Math.floor(Math.random() * 10) + 1;
    fetchPromises.push(Bingo.getArtist(id));
  }
  return Promise.all(fetchPromises);
}