使用async回调的findIndex结合mongoose.findById始终返回0的问题
问题原因
你在findIndex里使用了async回调函数,这会导致每个回调返回的都是Promise对象。在JavaScript中,Promise属于真值(Boolean(Promise) === true),所以findIndex会直接判定第一个元素满足条件,返回0——它根本不会等待异步查询完成再做判断。
findIndex是同步方法,只支持回调函数同步返回布尔值,无法适配异步逻辑。
解决方案
不能直接用findIndex处理异步判断,推荐先批量查询所有工单的时间信息,再用同步方法定位插入位置(这种方式也能减少数据库请求次数,提升性能):
const ticketToInsertTime = convertTime(ticket.visitTime); // 批量查询所有活跃工单的详情 const activeTicketDocs = await Promise.all( que.activeTickets.map(ticketId => Ticket.findById(ticketId).exec()) ); // 生成与原数组索引对应的时间数组,同时处理空文档的情况 const activeTicketTimes = activeTicketDocs.map(doc => { if (!doc?.visitTime) return 0; return convertTime(doc.visitTime); }); // 用同步的findIndex找到第一个时间大于插入时间的位置 const index = activeTicketTimes.findIndex(time => time > ticketToInsertTime); if (index < 0) { que.activeTickets.push(ticket._id); } else { que.activeTickets.splice(index, 0, ticket._id); } // 保存操作是异步的,必须加await确保数据写入数据库 await que.save();
额外注意点
- 原代码中的
que.save()没有加await,这会导致保存操作可能未完成就继续执行后续逻辑,容易引发数据不一致问题,必须添加await。 - 要处理
findById可能返回null的情况,避免convertTime收到undefined报错,比如上面代码中的空值判断。
内容的提问来源于stack exchange,提问作者qubrat
相关产品推荐
相关产品推荐

