我正在尝试循环并从Firestore获取不同的文档。如下面的代码所示,“文档ID”由名为“购物车”的数组提供。
我尝试过的编程逻辑是这样的,每次迭代中的while循环都从firestore获取文档,在第一个“ then”部分中,它将保存刚获取的数据,在第二个“ then”中,将增量“ i” ',然后执行下一个循环。
问题是while循环不等待获取请求完成。它只是不断循环和崩溃。
即使我设法以某种方式正确完成了循环部分,事情也是如此。我将如何管理程序的整体执行流程,以便仅在完成循环部分后才执行其他代码,因为下面的代码使用了循环部分更新的购物车数组。
let i = 0
while (i < cart.length) {
let element = cart[i]
db.collection(`products`).doc(element.productID).get().then((doc1) => {
element.mrp = doc1.data().mrp
element.ourPrice = doc1.data().ourPrice
return console.log('added price details')
}).then(() => {
i++;
return console.log(i)
}).catch((error) => {
// Re-throwing the error as an HttpsError so that the client gets the error details.
throw new functions.https.HttpsError('unknown', error.message, error);
});
}
return db.collection(`Users`).doc(`${uid}`).update({
orderHistory: admin.firestore.FieldValue.arrayUnion({
cart,
status: 'Placed',
orderPlacedTimestamp: timestamp,
outForDeliveryTimestamp: '',
deliveredTimestamp: ''
})
}).then(() => {
console.log("Order Placed Successfully");
})
答案 0 :(得分:1)
您的问题不是关于firebase
,您是在询问异步循环。您可以看到一些promises
示例here和async/await
here
您可以在promise中使用reduce。 请注意,所有的Promise都是同时创建的,但是对服务器的调用是一个接一个地完成的。
cart.reduce(
(promise, element) =>
promise.then(() => {
return db.collection(`products`)
.doc(element.productID)
.get()
.then(doc1 => {
element.mrp = doc1.data().mrp;
element.ourPrice = doc1.data().ourPrice;
});
}),
Promise.resolve()
);
如果可以,请改用async/await
。在这里,所有的诺言都是一个接一个地创建的。
async function fetchCart() {
for (const element of cart) {
const doc1 = await db.collection(`products`).doc(element.productID);
element.mrp = doc1.data().mrp;
element.ourPrice = doc1.data().ourPrice;
console.log('added price details');
}
}
答案 1 :(得分:0)
对Cloud Firestore的每次调用都是异步发生的。因此,您的while
循环会触发多个此类请求,但不会等待它们完成。
如果您的代码需要所有结果,则需要使用Promises来确保流程。您已经在while
循环中使用promise来获取doc1.data().mrp
。如果cart
是一个数组,则可以执行以下操作来收集有关何时加载数据的所有承诺:
var promises = cart.map(function(element) {
return db.collection(`products`).doc(element.productID).get().then((doc1) => {
return doc1.data();
});
});
现在您可以使用以下方法等待所有数据:
Promise.all(promises).then(function(datas) {
datas.forEach(function(data) {
console.log(data.mrp, data.ourPrice);
});
});
如果您使用的是现代环境,则可以使用async
/ await
来提取then
:
datas = away Promise.all(promises);
datas.forEach(function(data) {
console.log(data.mrp, data.ourPrice);
});