Node.js使用Mongoose时collection.find()总是最后执行如何解决?
问题解决方案
问题根本原因
Mongoose的collection.find()是异步IO操作,你传入的回调函数不会阻塞后续代码的执行,程序会先执行后面的同步代码lastFunction(),等数据库返回查询结果后,才会触发find的回调函数,所以才会出现执行顺序颠倒的问题。
解决方案
方案1:回调嵌套(最直观的适配修改)
把需要在查询完成后执行的逻辑,直接放到find的回调函数内部:
let totalTickets; // 定义getInitial,接收查询完成后要执行的回调函数作为参数 function getInitial(afterQueryCallback) { ticket.find(function (err, tickets) { // 新增错误判断,避免查询报错时程序崩溃 if (err) { console.error('查询失败:', err); return; } totalTickets = tickets.length; console.log("Done verifying tickets"); // 查询完成后执行传入的后续逻辑 afterQueryCallback(); }); } function lastFunction() { console.log("this should be the last to execute"); } // 调用getInitial,把lastFunction作为后续执行的参数传入 getInitial(lastFunction);
方案2:Promise链式调用(Mongoose原生支持)
Mongoose的查询方法本身返回Promise对象,可以用.then()链式调用处理后续逻辑:
let totalTickets; function getInitial() { // 直接返回find的Promise对象 return ticket.find() .then(tickets => { totalTickets = tickets.length; console.log("Done verifying tickets"); }) .catch(err => { console.error('查询失败:', err); }) } function lastFunction() { console.log("this should be the last to execute"); } // 用.then()指定查询完成后执行的逻辑 getInitial().then(lastFunction);
方案3:async/await语法(目前最推荐的简洁写法)
这是ES7推出的异步语法,和写同步代码的逻辑几乎一致,可读性最高:
let totalTickets; // 给函数加async标记 async function getInitial() { try { // 用await等待查询结果返回 const tickets = await ticket.find(); totalTickets = tickets.length; console.log("Done verifying tickets"); } catch (err) { console.error('查询失败:', err); } } function lastFunction() { console.log("this should be the last to execute"); } // 外层用自执行async函数包裹 (async function() { await getInitial(); lastFunction(); })()
内容的提问来源于stack exchange,提问作者Ike lagos
相关产品推荐
相关产品推荐

