如何尽早打破承诺链,在Express中发送错误?
我有这个请求处理程序,它看起来像这样:
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(...
我发现这个工作, 但是我担心使用更多的嵌套,因为我还需要检查video是否已经存储在数据库中处理之前,需要两个级别的缩进,也许更多。
我发现了另外两个答案( 其中一个 ),但是他们对我没有帮助。 我的问题特别与Bluebird和Express有关。
我想你只需要添加一个.catch
callback到你的承诺链,并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); }); });