如何在以响应状态更新对象数组之前等待getDownloadURL在映射函数中完成?

时间:2020-04-19 10:21:48

标签: reactjs firebase google-cloud-firestore

getImages() {
  const entries_copy = this.state.entries;
  entries_copy.map(entry => {
    storage.refFromURL(entry.sign_in_photo).getDownloadURL()
      .then((url) => {
        entry["inPhotoURL"] = url;
        storage.refFromURL(entry.sign_out_photo).getDownloadURL()
        .then((url) => {
          entry["outPhotoURL"] = url;
        });
      }).catch((error) => {
        // Handle any errors
      });
  });

  this.setState({entries: entries_copy});
}

我正在尝试检索图像的下载URL并将其存储在我的entrys对象数组中的我的entry对象中,但是我现在面临的问题是在检索URL之前调用setState,而我没有想法如何设置状态之前要等待它完成。我已经搜索了类似的问题,但是大多数问题是通过在then()内部执行解决的,但是对于我来说,我无法在then()内部执行解决,因为我必须等待所有条目被更新。我只是最近才开始在该项目中使用React,所以很抱歉,答案很明显。

2 个答案:

答案 0 :(得分:1)

这是因为代码是异步的。 您应该在.then()函数内调用setState。 我建议您阅读有关Java的Promises。它们是掌握该语言的重要方面。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

答案 1 :(得分:1)

除了@TomSlutsky的答案外,请注意,您需要正确chain进行承诺,并且不要忘记“始终返回结果,否则回调将无法捕获先前的承诺的结果”。

因此,您需要执行以下操作:

storage.refFromURL(entry.sign_in_photo).getDownloadURL()
      .then((url) => {
        entry["inPhotoURL"] = url;
        return storage.refFromURL(entry.sign_out_photo).getDownloadURL()
      })
      .then((url) => {
          entry["outPhotoURL"] = url;
          this.setState(...);
      })
      .catch((error) => {
          // Handle any errors
      });

还请注意在链的末尾如何调用catch()方法,请参阅文档以获取更多详细信息(以及可能的其他选项)。