如何解析if语句中的Promise?MongoDB批量写入前查重问题
解决MongoDB筛选未写入对象的异步问题
你的代码问题出在异步逻辑的处理上,具体原因和解决方法如下:
问题分析
- 直接比较Promise:第一个代码中
collection.countDocuments()返回的是Promise对象,直接和1比较时,Promise会被转为布尔值true,导致countDocuments(...) < 1永远为false,无法正确筛选。 - async回调导致filter失效:第二个代码里给filter的回调加了
async,但filter不会等待Promise完成,它会把每个async回调返回的Promise都视为truthy值,所以最终forWriting会保留原数组的所有元素,完全起不到过滤作用。
正确解决方案(高效版)
不要循环逐个查询数据库,而是一次性提取所有待检查的ID,用一次查询找出已存在的ID,再过滤原数组——这样能大幅减少数据库请求次数,提升效率:
// 1. 提取数组中所有待检查的id const allIds = testimonalsArray.map(item => item.id); // 2. 一次性查询数据库中已存在的id const existingIds = await collection.distinct('id', { id: { $in: allIds } }); // 3. 过滤出不在已存在列表中的对象 const forWriting = testimonalsArray.filter(item => !existingIds.includes(item.id)); console.log(forWriting);
备选方案(循环查询版,不推荐)
如果一定要逐个检查每个对象的存在性,需要先通过Promise.all等待所有异步查询完成,再根据结果过滤:
// 先获取每个对象是否已存在的结果数组 const existsStatusList = await Promise.all( testimonalsArray.map(item => collection.countDocuments({ id: item.id }).then(count => count > 0) ) ); // 根据结果数组过滤原数组 const forWriting = testimonalsArray.filter((item, index) => !existsStatusList[index]); console.log(forWriting);
注意:这个方案会发起和数组长度相同的数据库请求,数据量大时性能很差,优先用第一个方案。
内容的提问来源于stack exchange,提问作者Андрей Ребезов
相关产品推荐
相关产品推荐

