NodeJS打破了Promise

时间:2017-01-22 19:21:56

标签: node.js es6-promise

使用ES6 Promises,如何在以下场景中打破它?

addClient: function(request, response, next) {
    var id = mongo.validateString(request.body.id);

    mongo.Test.findOne({
        id: id
    })
    .then(client => {
        if (client) {
            // want to break here
            response.status(400).send({
                error: 'client already exists'
            });
        } else {
            return auth.hashPassword(mongo.validateString(request.body.secret));
        }
    })
    .then(hashedSecret => {
        // gets executed even if I don't return anything
        return new mongo.Test({
            name: mongo.validateString(request.body.name),
            id: id,
            secret: hashedSecret
        }).save();
    })
    .then(doc => {
        return response.status(201).send({
            client: {
                id: doc._id
            }
        });
    })
    .catch(err => {
        return next(err);
    });
}

我没有找到任何明确的文件说明如何打破这一点。 我可以将它放在第一个then内,而不是链接then,但是对于更复杂的请求,能够将它们链接起来会很好。

3 个答案:

答案 0 :(得分:0)

// gets executed even if I don't return anything
return new mongo.Test({
      name: mongo.validateString(request.body.name),
      id: id,
      secret: hashedSecret
    }).save();

即使您没有返回任何内容,也会执行此操作,因为此类内容的默认返回值为undefined。假设代码使用undefined

解析
  

如果此值不是承诺(包括未定义),则它将成为相关承诺的履行价值

this

上的Mozilla文档

您可以通过提前拒绝它来打破Promise链。

addClient: function (request, response, next) {
  var id = mongo.validateString(request.body.id);
  mongo.Test.findOne({
    id: id
  }).then(client => {
    if (client) {
      // reject with a type
      return Promise.reject({
        type: 'CLIENT_EXISTS'
      });
    }
    return auth.hashPassword(mongo.validateString(request.body.secret));
  }).then(hashedSecret => {
    // gets executed even if I don't return anything
    return new mongo.Test({
      name: mongo.validateString(request.body.name),
      id: id,
      secret: hashedSecret
    }).save();
  }).then(doc => {
    return response.status(201).send({
      client: {
        id: doc._id
      }
    });
  }).catch((err) => {
    // check type
    if (err.type === 'CLIENT_EXISTS') {
      return response.status(400).send({
        error: 'client already exists'
      });
    }
    return next(err);
  });
}

答案 1 :(得分:0)

如果你想打破一个承诺链,即不执行以下链式承诺链接,你可以通过返回一个永远无法解决的承诺,将未解决的承诺注入链中。

link_to [:admin, @form_defs]

答案 2 :(得分:0)

我通过返回一个新的Promise来破坏链条,这个Promise 被拒绝直接在同一行包含某个错误消息或对象。

由于我在最后一个catch块中收到错误并在一个地方返回我的响应。

betHelper.getPrediction(db, match_id, _userID)
    .then(function (prediction) {
        if (prediction != null) {
            return Promise.reject({error: "You already have a bet for this match", prediction: prediction});
        } else {
            //Prediction does not exist find user and match data
            return Promise.all([userHelper.findUserWithID(_userID, db), betHelper.getMatchData(match_id)]);
        }
    })
    .then(function (results) {
        let user = results[0];
        let game = betHelper.simplifiedMathData(results[1]);
        //Append user prediction
        return new Promise(betHelper.appendPrediction(db, user, game, localteam_score, visitorteam_score));
    })
    .then(function (prediction) {
        response.send(prediction);
    })
    .catch(function (err) {
        response.send(err);
    });