javascript - forEach() 不会更新数据库调用内的值

标签 javascript reactjs firebase google-cloud-firestore async-await

下面的代码片段表示数据库的监听器,该监听器在更改时返回多个对象(每个对象代表一个文档),然后它将获得 idquantity然后它将循环遍历每个对象并添加 object.price元素到每个对象并再次调用数据库,那么它将使用 quantity object.price元素来获取每个对象的总量,但问题是 quantityid没有按预期更新每个对象,而不是 quantity value 将始终是最后一个对象 quantity 的值。 但是当我尝试获取 id 的值时和quantity里面forEach()但是,一旦进入调用数据库的函数,一旦进入数据库,如下面的代码片段所示,问题仅发生在函数内部,并且在尝试获取 quantity 时会出现同样的问题。函数后面的值(我将在代码片段后面放置控制台中记录的内容的副本)

  useEffect(() => {
   
    db.collection("users").doc("4sfrRMB5ROMxXDvmVdwL").collection("basket").onSnapshot((docs) => {
        const oneSubTotal = [];
        let array = [] 
        let object = undefined;
        let id = undefined;
        let quantity = undefined;
        docs.forEach(  doc =>{
                object = doc.data()
                id = object.id;
                quantity = object.quantity
                
          
                console.log( " the quantity  before is " + quantity)
                console.log(" the id before is " + object.id)
                db.collection("products").doc(id).get().then( (e)=>{
                    object.price =  (e.data().price);
                    console.log( " the quantity inside is " + quantity)
                    console.log(" the id inside is " + id)
                    oneSubTotal.push(object.price * quantity)     
                     
                })
                    console.log( " the quantity after is " + quantity)
                    console.log(" the id after is " + id)
        })
  });
  }, [])

这是控制台中记录的内容

 the quantity  before is 9
 the id before is 1
 the quantity  before is 10
 the id before is 2
 the quantity inside is 10
 the id after is 2
 the quantity inside is 10
 the id after is 2
 the quantity after is 10
 the id after is 2
 the quantity after is 10
 the id after is 2

最佳答案

Tl;博士:

  • 创建一个名为 promises 的变量在循环之前并用空数组初始化它: let promises = [];
  • 在循环内,不执行 promise (通过调用 .thenawait ),而是将该 promise 推送到 promises数组
  • 一旦跳出循环,请调用 Promise.all(promises)解决promises内的所有 promise array 将返回所有响应的数组。

当您想在 for-each 循环(或与此相关的任何循环)内使用 Promise 时,不应在循环内执行该 Promise。相反,您应该将其插入 Promise 数组(位于循环之外),并在循环结束后,使用 Promise.all 立即解决所有这些问题。 。像这样:

useEffect(() => {
  db.collection("users")
    .doc("4sfrRMB5ROMxXDvmVdwL")
    .collection("basket")
    .onSnapshot((docs) => {
      const oneSubTotal = [];
      let array = [];
      let object = undefined;
      let id = undefined;
      let quantity = undefined;
      let promises = [];
      docs.forEach((doc) => {
        object = doc.data();
        id = object.id;
        quantity = object.quantity;
        console.log(" the quantity  before is " + quantity);
        console.log(" the id before is " + object.id);
        promises.push(db.collection("products").doc(id).get());
        console.log(" the quantity after is " + quantity); // quantity won't change here because we're not fulfilling the promise yet.
        console.log(" the id after is " + id); // same as above, this won't update before the promise is fulfilled, which is happening below
      });
      Promise.all(promises).then((allDocumentsFromForLoop) => {
        allDocumentsFromForLoop.map((document) => {
          console.log( " the quantity inside is " + quantity)
          console.log(" the id inside is " + document.data().id)
          oneSubTotal.push(document.data().price * quantity);
        });
      });
    });
}, []);

关于javascript - forEach() 不会更新数据库调用内的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66918168/

相关文章:

java - 使用 Firebase 创建包含随机生成问题的测验

javascript - GUA - 维度非交互

reactjs - 客户端 ReactJS 上的 process.env

ios - 在 Firebase (Swift) 中获取所有用户的同一个 child

javascript - 以父对象内的嵌套对象属性为目标

javascript - 如何在React Router v6中将路径url中的id作为组件属性传递

javascript - Firebase 存储 : download images to and put to img src in React map

java - 通过 LiveConnect 将二进制数据从 Javascript 传递到 Java applet

javascript - 随机数和 floor vs round 函数

javascript - 使用ajax symfony2加载 View