下面的代码片段表示数据库的监听器,该监听器在更改时返回多个对象(每个对象代表一个文档),然后它将获得 id
和 quantity
然后它将循环遍历每个对象并添加 object.price
元素到每个对象并再次调用数据库,那么它将使用 quantity
object.price
元素来获取每个对象的总量,但问题是 quantity
和 id
没有按预期更新每个对象,而不是 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 (通过调用
.then
或await
),而是将该 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/