为了账号安全,请及时绑定邮箱和手机立即绑定

在express+mongoose项目中使用ES7的async和await

标签:
JavaScript

不知道我是不是最后一个知道的,反正现在在工程中用的超级爽!
不需要bluebird,不需要co,把Promise 的then转化为同步代码简直high翻天。。。

要求:

mongoose v>4
node v>8

比如这样一个需求:在添加班级时,同步更新学校中的refs,如果用then来写:

  create(req, res, next) {    // 本学校下不允许创建重复专业
    const major = req.body.major;
    MajorSchema.findOne({      name: major.name,      school: major.school
    }).then(r => {      if (r) {        //constructor(message, status = httpStatus.INTERNAL_SERVER_ERROR, isPublic = false)
        return next(          new APIError(            '本学校下已有相同名称专业',
            httpStatus.INTERNAL_SERVER_ERROR,            true
          )
        );
      }      const item = new MajorSchema(major);
      item._id = mongoose.Types.ObjectId();
      item
        .save()
        .then(saved => {          //更新school中的引用
          SchoolSchema.findById(major.school).then(school => {            if (school) {              if (!school.majors.includes(saved._id)) {
                school.majors.push(saved._id)
                SchoolSchema.findByIdAndUpdate(major.school, {                  majors: school.majors
                }).then(savedSchools => {
                  res.json(saved);
                })
              }
            }
          })

        })
        .catch(e => next(e));
    });
  }

是不是很蛋疼?我竟然这样写完了几乎整个工程。。。
昨天发现了async,就象发现了新大陆,使用async-await,写这样的需求:移除专业时,同步移除学校中的refs:

  async remove(req, res, next) {    try {      const major = await MajorSchema.findByIdAndRemove(req.params.id).exec()      //删除学校中的ref
      if (major) {        const school = await SchoolSchema.findById(major.school).exec()        if (school && school.majors.indexOf(major.id)!==-1) {
          school.majors.splice(school.majors.findIndex(s => s === major.id), 1)          const updatedSchool = await SchoolSchema.findByIdAndUpdate(school._id, {            majors: school.majors
          }).exec()
          res.sendStatus(httpStatus.OK)
        }

      }
    } catch (err) {
      next(err)
    }

  }

首先是方法名上加async,再就是每个mongoose操作上加await,就变成了同步方法。
其次是,不要再每个操作捕捉错误,类似(err=>{next(err)})
实际上,我们在这里使用的是mongoose内置的Promise,这个Promise虽然有then()方法,但不完整,有一些操作不能实现。可以认为是阉割版的Promise。
如果要实现更多更完整的Promise功能,可以在操作方法后加上exec()。但依然是阉割版。
想获得完整的Promise体验的话,官方对此的解决方案是使用第三方的Promise库,比如bluebird或者co库,实际使用中,自带的promise我觉得很多情况下已经够用了



作者:Angeladaddy
链接:https://www.jianshu.com/p/71a8764a9c2d


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 1
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消