Nodejs封装MongoDB踩的坑(可与axios封装比较)

成功案例

1.按照官网的使用方法进行抽离封装(这里是一个insert方法)

image

2.config.js

把导入的变量封装成一个config.js文件

image

3.db.js

创建Db类的模块db.js

image

这里把MongoClient实例放在了Db类实例的clint属性上

image

连接数据库的方法,用Promise获取db实例

image

插入方法:用了 async 和 await 来获取 this.count() 执行完毕后 返回的Promise实例中的db

image

结果:成功插入数据库

image

image

开始遇坑

思考:insert方法上用了async和await ,不如把connect方法也改成用async和await,这样可以简洁很多

image

改好了!

运行!

image

直接报错!

这说的什么呢?

TypeError: Cannot read property 'collection' of undefined

async function without a catch block

这里有2个主要问题 (1.db实例里的 collection 没有定义)

打印db实例 => 结果是undiluted  => 进而推导是因为 return db时有错误抛出又没人接收

导致报 (2.async function without a catch block 错误)

下面进行错误接收:

image

运行还是报错,原因依旧是没有接收错误的catch。难道 try catch要用来裹 this.clint.connect  => 直接否定 => this.clint.connect 是个异步操作,try catch 只能检测同步代码

eq:原因如下

image

如果包裹了this.clint.connect  鬼知道你什么时候 throw err ,catch自然捕获不到数据

既然try catch没有写错,那为什么还是报错呢?

问题重点出在 db 为 undiluted 的句子上

image

不卖关子,直接说原因吧。

这里是重点:await 只能接收 Promise 实例!!!

1.上面 return db 的 db 如果(不是 Promise 实例 || 是Promise 实例,但没有给resolve传值) => await 默认会 new Promise()而且resolve(undfined) 。看到undefined没?这就是来源。

2.然后 return db 的 db 为什么不是Promise实例 ,因为this.clint.connect根本不是以Promise为原型来封装的,讲到这里欲哭无泪啊。在this.clint.connect的回调函数中返回的不是个Promise啊

误解来源:为什么自己会不由的以为mongo模块是可以返回Promise的,因为axios模块就是用Promise原型封装的模块 (- 。-)

结论:慎重使用async和await,在并发的异步函数中进行汇总处理也不要用await,而是用Promise.all

posted @ 2019-10-16 15:35  阴阳师先生  阅读(549)  评论(0)    收藏  举报