Express中Mongoose findById仅支持回调?回调在JS新框架的作用?
关于Express/Mongoose回调与查询对象的问题解答
1. 回调大量使用和JS特性的关系
是的,这和JS的异步非阻塞特性直接相关。Node.js(Express基于Node)的设计初衷就是处理高并发场景,异步操作能让程序在等待IO(比如数据库查询)时不卡住,继续处理其他请求。早期JS没有Promise、async/await这类语法糖,回调是实现异步逻辑的主要方式,所以Mongoose这类库一开始就大量采用回调模式。
2. 回调的作用
你的理解完全正确,回调的核心作用就是先执行耗时的异步任务(比如数据库查数据),等任务完成拿到结果后,再执行回调里的指定操作。比如你用findById(id, callback)时,Mongoose会先发起数据库查询请求,等数据库返回结果后,才会调用你传入的callback函数,把查到的实例对象作为参数传进去。
3. 无回调返回的查询对象和回调的关系
直接调用BookInstance.findById(req.params.id)返回的是Mongoose的Query查询对象,它不是最终的查询结果,只是一个用来构建、配置查询的对象(所以打印出来是BookInstance.findOne({...}))。
当你传入回调时,Mongoose会自动触发这个查询对象对应的数据库操作,等拿到结果后,把结果传给回调函数的参数。如果不用回调,你需要手动执行查询,比如用.exec()方法:
// 不用回调,手动执行查询获取结果 BookInstance.findById(req.params.id).exec() .then(bookinstance => { // 这里拿到的就是目标实例对象 console.log(bookinstance); }) .catch(err => { // 处理查询错误 });
或者用更简洁的async/await语法:
async function getBookInstance(req) { try { const bookinstance = await BookInstance.findById(req.params.id).exec(); console.log(bookinstance); } catch (err) { // 处理查询错误 } }
简单来说,回调是Mongoose帮你自动触发查询并处理结果的一种便捷方式;而无回调返回的Query对象,是让你可以手动控制查询的执行时机,或者添加更多查询条件后再执行。
内容的提问来源于stack exchange,提问作者Carl Sagan
相关产品推荐
相关产品推荐

