我有這樣的要求處理程序,它看起來像這樣:如何儘早打破承諾鏈,在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();
});
});
雖然顯示錯誤,許鏈demonstrably不破;下一個函數被調用。
我的問題是,我該如何早點破壞承諾鏈發送錯誤?
東西,我試過是引入一個多個級別的縮進:
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(...
我發現這個工作然而,我擔心使用更多的嵌套,因爲我還需要檢查視頻是否已經存儲在數據庫中,在處理之前,需要兩個的縮進級別,也許更多。
我發現了另外兩個答案(one),但它們對我沒有幫助。我的問題特別與Bluebird和Express有關。
不要認爲它是*破*,而是*分支*(如'if'語句),並且縮進感覺更加自然。作爲獎勵,如果你嵌套函數,你不需要那些醜陋的全局變量。 – Bergi
我明顯是C#開發人員 - 自2012年以來,我們擁有'async'關鍵字 - 因此很難。但是,感謝您的評論。 –
然後,您可能想要查看babel(具有'async'支持的ES6轉譯器)或Bluebirds'Promise.coroutine'。他們將所有'then'回調函數刪除,並允許您使用函數中的'return'。 – Bergi