用嵌套的Promises编写干净的代码

Ant*_*ton 5 javascript node.js promise

我正在编写一个与Apple通信以验证收据的应用.他们有一个沙盒和生产网址,你可以发布到.

与Apple通信时,如果您收到21007状态,则表示您要发布到生产URL,当您应该发布到沙箱时.

所以我写了一些代码来促进重试逻辑.这是我的代码的简化版本:

var request = require('request')
  , Q = require('q')
  ;

var postToService = function(data, url) {
  var deferred = Q.defer();
  var options = {
    data: data,
    url: url
  };

  request.post(options, function(err, response, body) {
    if (err) { 
      deferred.reject(err);
    } else if (hasErrors(response)) {
      deferred.reject(response);
    } else {
      deferred.resolve(body);
    }
  });

  return deferred.promise;
};

exports.verify = function(data) {
  var deferred = Q.defer();

  postToService(data, "https://production-url.com")
    .then(function(body) {
      deferred.resolve(body);
    })
    .fail(function(err) {
      if (err.code === 21007) {
        postToService(data, "https://sandbox-url.com")
          .then(function(body){
            deferred.resolve(body);
          })
          .fail(function(err) {
            deferred.reject(err);
          });
      } else {
        deferred.reject(err);
      }

    });

  return deferred.promise;
};
Run Code Online (Sandbox Code Playgroud)

验证函数中的重试部分非常丑陋,难以使用嵌套的promise进行读取.有没有更好的方法呢?

Stu*_*t K 5

您可以在拒绝处理程序中重新抛出错误以继续拒绝承诺,或者您可以返回新承诺来替换拒绝.

exports.verify = function(data) {
  return postToService(data, "https://production-url.com")
    .fail(function(err) {
      if (err.code === 21007) {
        return postToService(data, "https://sandbox-url.com")
      } else {
        throw err
      }
    });
};
Run Code Online (Sandbox Code Playgroud)