如何提前破坏承诺链以在Express中发送错误?

时间:2015-05-06 19:05:13

标签: javascript node.js express promise bluebird

我有这个请求处理程序,它看起来像这样:

router.post('/', function(req,res) { 
  var screencast;
  var channel;

  youtube.get(req.body.videoId).then(function(data) {
    screencast = data.screencast;
    channel = data.channel;
  }).then(function() {
    return connection.beginTransactionAsync();  
  }).then(function() {
    return connection.queryAsync('INSERT IGNORE INTO Channels SET ?', channel);
  }).then(function() {
    return connection.queryAsync('INSERT INTO Screencasts SET ?', screencast)
  }).then(function() {
    return connection.commit();
  }).error(function(e) {
    connection.rollback();
  });
});

有时我想提前破坏承诺链并发送错误。这是我试过的:

router.post('/', function(req,res) { 
  var screencast;
  var channel;

  youtube.get(req.body.videoId).then(function(data) {
    if (data === null) {
      res.send('error: video does not exist.');
      return;
    }
    screencast = data.screencast;
    channel = data.channel;
  }).then(function() {
    console.log('trace: starting transaction');
    return connection.beginTransactionAsync();  
  }).then(function() {
    return connection.queryAsync('INSERT IGNORE INTO Channels SET ?', channel);
  }).then(function() {
    return connection.queryAsync('INSERT INTO Screencasts SET ?', screencast)
  }).then(function() {
    return connection.commit();
  }).error(function(e) {
    connection.rollback();
  });
});

显示错误 时,承诺链明显不会中断;调用下一个函数。

我的问题是,如何提前破坏承诺链以发送错误?

我尝试的是引入一个更多级别的缩进:

youtube.get(req.body.videoId).then(function(data) {
  if (data === null) {
    res.send('error: video does not exist.');
    return;
  }
  connection.beginTransactionAsync().then(function() {
    return connection.queryAsync('INSERT IGNORE INTO Channels SET ?', channel);
  }).then(...

我发现这个工作但是,我很担心使用更多的嵌套,因为我还需要检查视频是否已经在处理之前存储在数据库中,需要两个< / strong>缩进程度,可能更多。

我找到了另外两个回答(one)然而,他们对我没有帮助。我的问题与Bluebird和Express有关。

1 个答案:

答案 0 :(得分:3)

我认为只要你遇到一个应该突破承诺的问题,你就需要在你的承诺链和.catch添加一个throw回调。

router.post('/', function(req,res) { 
  var screencast;
  var channel;

  youtube.get(req.body.videoId).then(function(data) {
    if (data === null) {
      throw new Error('video does not exist.');
    }
    screencast = data.screencast;
    channel = data.channel;
  }).then(function() {
    console.log('trace: starting transaction');
    return connection.beginTransactionAsync();  
  }).then(function() {
    return connection.queryAsync('INSERT IGNORE INTO Channels SET ?', channel);
  }).then(function() {
    return connection.queryAsync('INSERT INTO Screencasts SET ?', screencast)
  }).then(function() {
    return connection.commit();
  }).error(function(e) {
    connection.rollback();
  }).catch(function(err){
    res.send("error: " + err);
  });
});