带有 Promise 和回调的猫鼬

Posted

技术标签:

【中文标题】带有 Promise 和回调的猫鼬【英文标题】:Mongoose with Promise and callback 【发布时间】:2021-01-28 23:39:22 【问题描述】:

我无法理解以下代码在连接 MongoDB 时的区别。

1: mongoose.connect(url,  useNewUrlParser: true, useUnifiedTopology: true , (err) => 
if (err) 
    return err

console.log('connected to DB!');
)

2: mongoose.connect(url,  useNewUrlParser: true, useUnifiedTopology: true )
mongoose.connection
   .on('error', (error) => 
        console.warn(error))
   .once('open', () => 
        console.log('connected to DB!'))

3: mongoose.connect(url,  useNewUrlParser: true, useUnifiedTopology: true )
    .then(() => console.log('connected to DB!'))
    .catch(error => console.log(error))

所以从他们的理解来看,mongoose.connect 返回一个 Promise,我们必须使用 .then.catchaync/await 来处理 Promise,但在这里它也使用了回调函数。 有人可以向我解释这 3 种方法吗?

【问题讨论】:

在您的三个示例中,唯一的区别是错误的处理方式(console.log vs console.warn vs 忽略)。一般来说,他们做同样的事情,不确定你到底想要解释什么。看看实际代码中的用法。 我实际上是在问是否可以始终使用回调函数处理承诺?因为我知道我们使用 .then 和 async/await 来处理它 我还是不清楚。你传递给thencatch 的是回调函数。是这样吗? 【参考方案1】:

数字 1 和 3 做同样的事情:它们处理初始连接成功/失败。由于不是每个人都使用 Promise,因此它们也提供了一种通过回调来处理它的方法。在这两种情况下,回调/promise 将在第一次连接期间被调用,稍后执行期间的失败则不会。您当然应该一次只使用一个功能,回调或承诺。

第二个添加了一个事件监听器,它会在每次连接发生错误时触发其回调,而不仅仅是在初始连接期间。除了数字 1 和 3 之外,它还可用于处理程序生命周期中的错误。

更多信息在这里:https://mongoosejs.com/docs/connections.html#error-handling

【讨论】:

谢谢,但据我所知,我使用 .then/.catch 或 async/await 处理承诺。从来没有用回调处理过 Promise,我很困惑 您在承诺处理方面是正确的。您不使用回调处理 Promise:如果提供,猫鼬会调用您的回调,否则它会返回 Promise。【参考方案2】:

你需要学习和考虑的两件事:

    了解 Promise 与回调;理解错误处理 (试着抓);理解概念处理(承诺; 异步/等待;回调) 代码 #1、#2 和 #3 的含义和作用

关于概念

最近的一些不错的链接:

在Promises vs Callback 和Using Promises and Chaining Concept 在try... catch 在async/await

所以,首先:我建议您充分理解上述不同的概念以及如何处理它们的想法。

然后:解耦您在问题中谈论的不同概念。它们的含义不同,并且没有标准的使用方式:您必须根据自己的需要和对代码的处理来决定它们的用法。

总结一下:

承诺

表示异步操作最终完成或失败的对象

回调

传递给另一个函数的函数,一旦达到特定状态(返回点;发生错误;做出决定等),后者将调用前​​者。

异步/等待

这个概念使异步代码看起来和表现得像同步代码;它简化了同步使用 Promise 并在一组 Promise 上执行某些行为的行为

尝试...抓住

处理异常的方法 (!!!) - 不一定是处理错误的方法(通常错误会引发异常,但您也可能希望或需要将其用于不同目的)

正如您所见,所有这些范例都有不同的含义,并且您可以看到它们以特定方式结合使用。但是,您不一定要以通常看到的方式使用它们。

关于代码

当您完全理解这些概念后,这是最容易的部分:

#1:使用回调机制 --> 你将连接到一个 MongoDB 数据库,或者,如果在建立连接的过程中发生错误,你将返回一个错误(通过回调机制) #2:混合使用函数调用mongoose.connect 和链接 --> 连接时您没有处理最终错误(因此这最终会成为问题);然后,如果已连接,如果在连接打开期间发生错误,您将向控制台写入警告;当连接打开时(如果前面的语句mongoose.connect(...) 成功,则说明数据库已连接 #3:仅使用链接概念 --> 您正在尝试建立连接;然后,如果成功,您已连接;然后,如果不成功,你会发现错误

希望这会有所帮助。 ;)

【讨论】:

以上是关于带有 Promise 和回调的猫鼬的主要内容,如果未能解决你的问题,请参考以下文章

带有嵌套地图的 Promise.all .. 第一张地图仅适用于其他人在猫鼬中返回空对象

使用 Q 的猫鼬嵌套填充不起作用

没有回调的猫鼬更新

从 薛定谔的猫 聊到 Event loop

Javascript 像 Java 8 上的“Promise.all”(可能带有 lambdas)

介绍Promise构造函数的几种方法