我有这段代码正在检查我的userContacts ID是否在另一个集合中,并且我将返回所有匹配项。
async function fetchCommonNumbers() {
var commonNumbers = [];
let contactsReference = admin.firestore().collection("user_contacts").doc("iNaYVsDCg3PWsDu67h75xZ9v2vh1").collection("contacts");
const dbContactReference = admin.firestore().collection('db_contacts_meta');
userContacts = await contactsReference.get();
userContacts = userContacts.docs;
await Promise.all(
userContacts.map(userContact => {
const DocumentID = userContact.ref.id;
//Check if Document exists
return dbContactReference.doc(DocumentID).get().then(dbContact => {
if (dbContact.exists) {
console.log(DocumentID);
commonNumbers.push(dbContact.data());
}
});
}));
return Promise.resolve(commonNumbers);
}
我只需要返回X个匹配项,而不是全部,因为以后我将拥有一百万条记录,并且我想减少处理时间。
当commonNumbers中包含X个项目时,如何使Promise.all停止?
答案 0 :(得分:0)
当前没有实现可撤销的承诺(更多信息可以在enter link description here上找到),
如果需要,您可以定义自己的“可取消承诺”,以包装正常的承诺。
答案 1 :(得分:0)
您不能真正兑现承诺停止。但是,由于您要减少数据库调用次数,因此您可以 选择性地兑现您的诺言。
例如,您可以在map
函数中包含条件语句。像这样
if commonNumbers.length < maxLength
然后给我一个承诺,其中包含数据库调用false
)您的诺言仍然存在,但是您将将数据库调用的数量限制为必要的。看起来像这样
const arr = [1, 2, 3, 4, 5, 6];
const buffer = [];
const maxLenBuffer = 3;
const p = Promise.all(
arr.map(n => {
if (buffer.length < maxLenBuffer) {
buffer.push(n);
return Promise.resolve(n);
} else {
// There's still a promise to be resolved, but it's not a HTTP call
// This gives you the gain of performance you're looking for
return Promise.resolve(false);
}
})
);
p.then(() => console.log(buffer));
虽然此可以减少您的数据库调用,但实际的调用次数可能比您指定的最大稍高。这是由于调用的异步性质
答案 2 :(得分:0)
建议您不要使用limit方法来执行存储操作,而要避免违反承诺。
您只能查询X个记录,该X可以是硬编码的,也可以来自用户。像这样:
documentRef.orderBy("name").limit(3).get()