【问题标题】:JavaScript arrays are not sameJavaScript 数组不一样
【发布时间】:2019-05-26 13:03:15
【问题描述】:

我在这里附上我的控制台日志结果的屏幕截图。它们都是对象。但它们并不相同。可能是什么问题呢?一个正在显示

(5) [{..},{..},{..},{..},{..}]

另一个只是显示[]

let tmp_array = [];
    this.database.ref('/users/').once('value', (snapshot) => {
      snapshot.forEach( (childSnapshot) => {
      var key = (childSnapshot.val() && childSnapshot.key) || 'Anonymous'; 
      var name = (childSnapshot.val() && childSnapshot.val().name) || 'Anonymous';    
      var email = (childSnapshot.val() && childSnapshot.val().email) || 'Anonymous';
      tmp_array.push({ key: key, email: email, name: name });
    });
    this.setState({ data: tmp_array });
    this.getImageList(tmp_array);
    console.log(tmp_array);
 });


let tmp_array2 = [];
    lodash.forEach(tmp_array, (value, key) => {
      this.storage.ref().child(value.key + '.jpg').getDownloadURL().then(function (url) {
        tmp_array2.push({ id: value.key, image: url });
    });
});
this.setState({ image: tmp_array2 });
console.log(tmp_array2);

【问题讨论】:

  • 数组不一样。问题是什么?这个问题的意义是 0。
  • 如果您不include relevant part of your code,Stack Overflow 用户将无法回答您。请编辑您的问题
  • 我添加了我的代码,请检查它

标签: javascript arrays reactjs firebase


【解决方案1】:

欢迎使用 Web API 进行编程。这里有一个典型的异步问题。我将解释您的代码中发生了什么,然后为您提供解决方案的第一步,指出一些进一步的考虑因素,最后提供包含更多信息的链接,供您阅读这个令人难以置信的常见(但最初同样令人困惑)主题。

问题:下载地址是异步加载的

您的代码调用getDownloadURL,这是异步发生的。这意味着您的其他代码在加载 URL 时继续。然后在加载 URL 时,使用 URL 调用您的回调。这意味着任何需要 URL 的代码都必须在回调中。

如果你只是简单的代码和添加一些日志语句,这是最容易看到的:

console.log("Before starting getDownloadURL");
this.storage.ref().child(value.key + '.jpg').getDownloadURL().then(function (url) {
    console.log("Got download URL");
});
console.log("After starting getDownloadURL");

当您运行此代码时,它会打印:

开始getDownloadURL之前

启动getDownloadURL后

获取下载地址

这可能不是您期望的顺序,但它完全解释了为什么当您打印它时数组是空的:URL 还没有加载,所以它们还没有被添加到数组中。

解决方法:把所有需要下载地址的代码都放在回调里面

要解决这个问题,所有需要从数据库下载 URL 的代码都必须回调中(或者从那里调用)。所以第一步是:

let tmp_array2 = [];
lodash.forEach(tmp_array, (value, key) => {
  this.storage.ref().child(value.key + '.jpg').getDownloadURL().then(function (url) {
    tmp_array2.push({ id: value.key, image: url });
    this.setState({ image: tmp_array2 });
    console.log(tmp_array2);
  });
});

当您运行此程序时,您会看到它记录数组的频率与子节点/图像的频率一样。每次它获取一个下载 URL(记住:这是异步发生的)时,它会将它添加到数组中,然后告诉 React 状态已经改变(它可以更新 UI)。

一些额外的注意事项和问题

我上一个代码sn-p还有更多的陷阱:

  1. 反复调用setState() 可能会导致UI 仅部分更新或闪烁。在这种情况下,请考虑在调用 setState 之前检查您是否已获取所有下载 URL,例如:if (tmp_array2.length === tmp_array.length) this.setState({ image: tmp_array2 });
  2. 下载 URL 调用是异步发生的,并且可能(我认为,这取决于该 API 的后端实现)以不同于调用它们的顺序完成。换句话说:第二张图片的下载地址可能会在第一张图片的下载地址之前返回。如果这是您的应用程序所关心的问题,请确保在 tmp_array2 中复制图像的其他信息(我认为您已经这样做了),或者考虑以允许您将它们关联回的方式存储下载 URL tmp_array 中的项目。

更多信息

正如我在开头所说的:对于刚接触异步 API 的开发人员来说,这是一个非常常见的问题。因此,如果您搜索它们,可能还有数百个相关问题/链接。以下是我最喜欢的一些:

【讨论】:

    【解决方案2】:

    A [] 是一个空数组。另一个 [{..},{..},{..},{..},{..}] 是一个包含 5 个对象的数组。由于您没有指定哪个临时数组代表哪个记录数组,我无法帮助您确定为什么一个数组为空。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-04
      • 1970-01-01
      • 2013-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多