使用 mongoose findbyid 和express从数据库获取对象只能与回调一起使用吗?回调在较新的 js 框架中的重要性?

问题描述 投票:0回答:1

我正在 MDN 文档上做快速本地库教程,并想尝试在不使用回调方法的情况下返回对象。

当像这样将 id 的请求对象参数传递给 findById mongoose 方法并登录到控制台时,这是 bookinstance 的内容:

var bookinstance = BookInstance.findById(req.params.id);

像这样将 id 和回调函数传递给 findById 方法时

BookInstance.findOne({ _id: '63e17d2395d1d4e11604cf22' })

并登录到控制台,输出了预期的书籍实例对象:

BookInstance.findById(req.params.id, function(err, instance) { if (err) { next(err); } console.log('findById callback: ' + instance); res.render("bookinstance_delete", { title: "Book Instance Delete", id: instance._id, imprint: instance.imprint, book: instance.book }) })

这通常与 javascript 有关吗?这是我第一次接触express、node、mongoose以及所有这些基于javascript的框架和技术,它们似乎都大量使用回调。回调的目的只是为了有一种方式说,嘿,执行这个任务,当你完成后,执行这个任务?

当我没有使用回调时,返回的对象是对象和方法(findone),执行时会给我 bookinstance 对象和属性。那么回调函数会将该对象作为实例参数,执行它并返回该对象吗?这是怎么回事吗?

javascript node.js express mongoose callback
1个回答
0
投票

但是,在异步编程中,任务不需要等待每一行代码完成才能开始另一行代码。例如,为什么您的程序必须等待数据库查询完成才能读取文件或上传图像。这些耗时的任务肯定可以同时完成吗?在同步编程中,完成这些任务所需的时间被加在一起,但在异步编程中,您可以同时执行这些任务,所以您应该这样做。

但是随之而来的问题是如何知道每个异步何时完成。在同步编程中,您的代码只会移动到下一行代码。在 JavaScript/Node.js 异步编程中,有回调,它 本质上,只是用结果调用的另一个函数 异步操作。

您似乎已经掌握了这个概念:

所以回调的目的只是为了有一种方式说,嘿,执行这个任务,当你完成后,执行这个任务?

回调模式只是 JavaScript 中的几种设计模式之一,可以处理异步任务,但它们也有其缺点 -
回调地狱

在现代 Node.js 中,我们有更新的设计模式,可以使用

Promises

async/await 处理控制流。它们具有更好的语法,并且更易于阅读、编写和调试。由于 Node.js 是单线程,这些较新的设计模式使得运行不会阻塞单线程的响应式 Web 应用程序变得更加简单。 上面使用回调模式的示例:

findById callback: { _id: new ObjectId("63e17d2395d1d4e11604cf22"), book: new ObjectId("63e17d2395d1d4e11604cf16"), imprint: 'New York Tom Doherty Associates, 2016.', status: 'Available', due_back: 2023-02-06T22:20:19.928Z, __v: 0 }

是一种非常过时的方法,您现在找到的所有文档都概述了 
BookInstance.findById(req.params.id, function(err, instance) {...});

Promises
模式。
虽然 mongoose 查询不是 Promises,但您仍然可以使用带有 

async/await

then
块的 Promises 实现:
catch

这是 
BookInstance.findById(req.params.id).then((doc) => { console.log('Found Instance: ', doc); }) .catch((err) => { console.log(err); });

模式:

async/await

一般来说,您会发现 mongoose 和 Node.js 的一个问题是,如果在进行数据库查询时不使用 
app.get('/books/:id', async (req, res) => { // < Note the use of async keyword try { const result = await BookInstance.findById(req.params.id); // < Note the use of await keyword console.log(result); } catch(err) { console.log(err); } });

Promises
模式,您将遇到意想不到的结果。例如你写道:

当我没有使用回调时,返回的对象是对象和方法(findone),

这可能适用于一个小型查询,但如果集合中有数千或数百万个文档,并且您对它们执行了查询,则您的脚本实际上可能会在查询完成之前结束,并且不会返回任何文档。运行查询可能需要 200 毫秒,但您的脚本从开始到结束运行只花了 150 毫秒。如果没有回调、Promise 或 async/await,您的代码就会移至末尾,而您将无法从数据库中获得结果。

© www.soinside.com 2019 - 2024. All rights reserved.