使用Async/await与mongoose

3
我正在参加由Stephen Grinder授课的高级NodeJS课程,我们正在测试Redis中的缓存。
当我运行应用程序并到达给定路由时,我会遇到以下错误: DeprecationWarning: Mongoose: mpromise(mongoose的默认promise库)已弃用,请插入自己的promise库:http://mongoosejs.com/docs/promises.html 还有另一个看起来像这样的错误: UnhandledPromiseRejectionWarning:未处理的承诺拒绝。此错误要么是在async函数内部抛出而没有catch块,要么是拒绝了未经处理的承诺而没有使用.catch()处理它(拒绝ID:1)[0](节点:11896)[DEP0018]不受支持的承诺拒绝已被弃用。将来,未处理的promise拒绝将以非零退出代码终止Node.js进程。 [0]从MongoDb提供服务。
现在,正如所述,我粗略地查看了一下,似乎他们的文档没有讨论异步和等待。

这是抛出错误的API路由

  app.get('/api/blogs', requireLogin, async (req, res) => {
    const redis = require('redis')
    const redisURL = 'redis://127.0.0.1:6379';
    const  client = redis.createClient(redisURL);
    const util = require('util')
    client.get = util.promisify(client.get)
    const cachedBlog = await client.get(req.user.id) 
    if (cachedBlog)  return res.send(JSON.parse(cachedBlogs))
    console.log("serving from MongoDb")
    const blogs = await Blog.find({_user: req.user.id})
    client.set(req.user.id, JSON.parse(blogs))
    res.send(blogs);
  });

具体来说,这里是这行。
 const blogs = await Blog.find({_user: req.user.id})

在哪里

const Blog = mongoose.model('Blog');

注意:简单来说,为了解释缓存,Stephen Grinder 故意将其设置在根目录中。 [问题:] 请问有人可以告诉我如何使用 async/await(就像我当前在路由中所做的那样),而不会抛出任何错误吗?

2
不确定为什么这里的答案被删除,或者为什么会有这么多来回评论,但是“警告”(不是“错误”)来自于缺少mongoose.Promise = global.Promise或类似的设置。文档参考在问题的引用页面下方进一步阐述了此问题插入您自己的Promises库,虽然文档“示例”使用了Bluebird,但它并不专属于该库,而是适用于任何Promise实现。 - Neil Lunn
2
另一方面,“UnhandledPromiseRejectionWarning:”是指您在没有在“try..catch”块中明确解决Promise的情况下使用“async/await”的用法。因此,这是一个警告(再次强调,不是“错误”)。但由于您实际上没有在问题中包含该代码的上下文,我们无法“明确”告诉您要纠正哪里,并且只能“通用”地回复。我建议访问https://www.google.com/search?q=async+await+UnhandledPromiseRejectionWarning,其中有大量有用的材料,包括错误示例和如何进行更正。 - Neil Lunn
@NeilLunn 提到了这个问题:https://dev59.com/EFQK5IYBdhLWcg3wbfaW#51862948我们在使用 bluebird 时,是否需要使用 mongoose.Promise = global.Promise?现在不再需要吗?此外,我最初使用的是 Stephen Grinder 的 Advance NodeJs boiler plate https://github.com/StephenGrider/AdvancedNodeStarter 上述代码来自他的博客路由 (https://github.com/StephenGrider/AdvancedNodeStarter/blob/master/routes/blogRoutes.js)(您看不到其中的 redis 部分)。 - Alwaysblue
请再次阅读所有内容和相关参考资料。这与“蓝鸟”或其他错误答案无关。再次强调,“警告”不是“错误”。 - Neil Lunn
1个回答

6

这里有两个问题。

1:您没有为Mongoose设置Promises,因此请设置它。

mongoose.Promise = global.Promise

2:当您使用async/await时,需要将代码放在try/catch块中。

try { 

   // your code

} catch(e) {

  console.log(e);

}

在您的情况下,代码应该像这样。
app.get('/api/blogs', requireLogin, async (req, res) => {
   try {
      const redis = require('redis')
      const redisURL = 'redis://127.0.0.1:6379';
      const  client = redis.createClient(redisURL);
      const util = require('util')
      client.get = util.promisify(client.get)
      const cachedBlog = await client.get(req.user.id) 
      if (cachedBlog)  return res.send(JSON.parse(cachedBlogs))
      console.log("serving from MongoDb")
      const blogs = await Blog.find({_user: req.user.id})
      client.set(req.user.id, JSON.parse(blogs))
      res.send(blogs);
  } catch(e) {
      console.log(e);
  }
});

你不应该在调用Mongoose的“Blog.find()”函数后使用.exec()来执行吗?我对异步编程很陌生,有点困惑。@AbhishekSingh - chopeds

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接