美文网首页让前端飞Web前端之路
在express+mongoose项目中使用ES7的async和

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

作者: Angeladaddy | 来源:发表于2018-05-24 16:37 被阅读8次

    不知道我是不是最后一个知道的,反正现在在工程中用的超级爽!
    不需要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库,详见:http://mongoosejs.com/docs/promises.html,实际使用中,自带的promise我觉得很多情况下已经够用了。

    相关文章

      网友评论

        本文标题:在express+mongoose项目中使用ES7的async和

        本文链接:https://www.haomeiwen.com/subject/xuusjftx.html