异步瀑布等同于Q.

时间:2013-11-18 21:30:42

标签: javascript asynchronous promise deferred q

我有一个页面,这是一个帐户设置页面。在其中,我允许我的用户更新他们的头像(如果他们已附加图像),更改他们的电子邮件(如果它已从原始更改),并更改他们的名称和密码。

现在,我正在使用异步的waterfall方法,但我更换了Q的异步,因为我更喜欢语法(和api)。我想知道这是否是我应该使用Q代替异步瀑布的方式。

我正在做这样的事情:

exports.settingsAccountPOST = function(req, res) {
  var doesEmailExist = function() {
    var deferred = Q.defer();

    User.findByEmail({
      email: req.body.email
    }, function(err, user) {
      if (err) {
        deferred.reject(err);
      } else {
        deferred.resolve(user);
      }
    });
    return deferred.promise;
  };

  var updateEmail = function(email) {
    var deferred = Q.defer();

    User.updateEmail({
      userId : req.session.user.id,
      email : req.body.email
    }, function(err, updated) {
      if (err) {
        deferred.reject(err);
      } else {
        deferred.resolve(updated);
      }
    });
    return deferred.promise;
  };

  var updateName = function() {
    var deferred = Q.defer();

    if (req.body.name) {
      User.updateName({
        userId: req.session.user.id,
        name: req.body.name
      }, function(err, updated) {
        if (err) {
          deferred.reject(err);
        } else {
          deferred.resolve(updated);
        }
      });
      return deferred.promise;
    }
  };

  doesEmailExist().then(function(email) {
    if (!email) {
      return(updateEmail(email));
    }
  }).then(function() {
    return(updateName())
  }).then(function() {
    res.redirect('/account')
  });
};

假设使用的电子邮件地址出错。有没有办法将它“传递”到最后一个电话?使用案例:正确更新密码,但电子邮件更新不起作用,因此我想向用户显示会话闪存,告诉他们他们已正确更新密码,但更新电子邮件时出现问题。

我正在查看文档,似乎我可能需要使用:

.fin(function () {
});

这是对的吗?如果是这样,我该怎么做呢?只需将链中发生的错误推送到对象,然后遍历所有错误并将其显示给用户?或者只是立即返回并显示错误?

1 个答案:

答案 0 :(得分:4)

如果您使用Q.defer,通常会出错。

var findByEmail = Q.nbind(User.findByEmail, User);
var updateEmail = Q.nbind(User.updateEmail, User);
var updateName = Q.nbind(User.updateName, User);

//later on...

exports.settingsAccountPOST = function (req, res) {
    findByEmail({
        email: req.body.email
    })
    .then(function (user) {
        if (!user) {
            return updateEmail({
                userId: req.session.user.id,
                email: req.body.email
            });
        }
    })
    .then(function () {
        return updateName({
            userId: req.session.user.id,
            name: req.body.name
        })
    })
    .then(function () {
        res.redirect("/account");
    })
    .catch(function(e){
        //Handle any error
    });
};