如何正确链接承诺相互依赖的呼叫?

时间:2016-06-27 19:52:25

标签: javascript node.js promise bluebird

我有以下代码:

const request = require('request-promise');

request(validateEmailOptions).then(function(result) {
  if (result.valid) {
    request(createUserOptions).then(function (response) {
      if (response.updatePassword) {
         request(modifyUserOptions).then(function (response) {
          return res.redirect('/signin');
        }).catch(function(error) {
          return res.redirect('/error');
        });
      }
    }).catch(function(error) {
      return res.redirect('/error');
    });
  } else {
    return res.redirect('/error');
  }
})
.catch(function (reason) {
  return res.redirect('/error');
});

基本上,它是一个请求呼叫链,每个呼叫都基于前一个呼叫的结果。问题是我在每种情况下都有更多的行,因此,我的代码变得臃肿,难以阅读和遵循。我想知道是否有更好的方法使用request-promises或简单地请求和bluebird来编写调用链。

1 个答案:

答案 0 :(得分:4)

你可以取消承诺。想一想:

f(a).then(function(a) {
  return g(b).then(function(b) {
    return h(c)
  })
})

与:

相同
f(a).then(function(a) {
  return g(b)
}).then(function(b) {
  return h(c)
})

我建议尽早失败,这意味着首先处理错误条件,并且如果需要,可以使用有意义的错误消息来记录它们。最后,您可以传播错误并在单个catch中处理它。将它放在代码的上下文中:

request(validateEmailOptions).then(function(result) {
  if (!result.valid) {
    throw new Error('Result is not valid');
  }
  return request(createUserOptions);
}).then(function(response) {
  if (!response.updatePassword) {
    throw new Error('Password is not updated');
  }
  return request(modifyUserOptions);
}).then(function(response) {
  return res.redirect('/signin');
}).catch(function(error) {
  // you may want to log the error here
  return res.redirect('/error');
});