我正在构建一个用于创建零售标牌的Web应用程序。 Firestore拥有有关标志的信息,如果用户单击“删除所有标志”,我希望能够删除所有标志。然后将出现一个对话框,要求用户确认删除数据库中的所有标志。如果它们确认,则应从Firestore中删除所有标志。
每个标志的文档ID存储在名为signIds
的数组中。我希望能够遍历signIds
并从Firestore的signs
集合中删除每个文档。一旦所有的Promise都解决了,我想返回一个Promise并在mounted()
的事件处理程序中解决它。
我尝试在代码的不同位置返回Promise,但无济于事。我也尝试使用async
和await
,但这似乎有相同的问题。
data() {
return {
signIds: [],
}
},
methods: {
showModal(message, type) {
this.$root.$emit('openModal', {
closed: false,
text: message,
type: type
})
},
emptyQueue() {
let self = this;
let deleted = 0;
for (let id of self.signIds) {
database.collection("signs").doc(id).delete()
.then(() => {
console.log("Document successfully deleted!");
deleted++;
}).catch((error) => {
console.error("Error removing document: ", error);
});
}
// Once all signs are deleted, return new Promise
return new Promise((resolve, reject) => {
return (deleted === self.signIds.length) ? resolve() : reject(new Error('An error occurred while deleting signs.'));
});
}
},
created() {
// Get and store the document id for each sign
database.collection("signs").get()
.then(snapshot => {
snapshot.forEach(doc => {
this.signIds.push(doc.id);
})
});
},
mounted() {
// When the user clicks 'OK' on the dialog, delete all signs from the database
this.emptyQueue()
.then(() => {
setTimeout(function() {
self.showModal('All signs were successfully removed.', 'success');
}, 300);
}).catch(() => {
setTimeout(function() {
self.showModal('An error has occurred. Some signs were not removed.', 'error');
}, 300);
})
}
我希望新的Promise在Firestore的Promises解决后会返回,但是目前,新的Promise在for
循环完成后立即返回。
答案 0 :(得分:4)
您通过signIds
的{{1}}进行的当前迭代没有与其他任何内容相链接-Promises
承诺目前不在任何地方使用。最好将每个.delete()
.map
到数组中的id
,然后在该数组上使用Promise
。如果错误由使用者处理,则无需Promise.all
中的catch
引发新的错误-而是仅返回Promise链,并避免使用explicit Promise construction anti-pattern:>
emptyQueue
如果emptyQueue() {
return Promise.all(
this.signIds.map(id => (
database.collection("signs").doc(id).delete()
))
);
}
调用中的任何一个导致错误,则该错误将渗透到您的
.delete()
通过this.emptyQueue()
// ...
.catch(() => {
...
});
自动部分。
答案 1 :(得分:1)
答案 2 :(得分:1)
您应该可以使用batch
来执行此操作,并且代码应类似于以下内容:
// start a batch
var batch = database.batch();
for (let id of self.signIds) {
// for each, add a delete operation to the batch
batch.delete(database.collection("signs").doc(id));
}
// Commit the batch
batch.commit();