簡體   English   中英

Coffeescript具有回調和簡化的錯誤處理

[英]Coffeescript with callbacks & simplified error handling

我希望能夠從這個coffeescript代碼重構錯誤處理:

# Do some stuff with 2 levels of asynchronous callbacks and error handling
vote = (res, data) ->
  Case.findOne { caseId: data.id }, (err, mycase) ->
    if err
      console.error 'Vote failed'
    else
      myvote = new Vote
        case: mycase._id
      myvote.save (err) ->
        if err
          console.error 'Could not add vote'
        else
          console.log 'Success!'

這樣的事情:

# Run my function, do error handling, and run the callback if no error
runit = (func, arg, errmsg, callback) ->
  func arg, (err, docs) ->
    if err
      console.log errmsg + ': ' + err
    else
      callback docs

# Original code, simplified
vote = (res, data) ->
  runit Case.findOne { caseId: data.id }, 'Vote failed', (mycase) ->        
      myvote = new Vote
        case: mycase._id
      runit myvote.save, 'Could not add vote', () ->   
          console.log 'Success!'

顯然, runit函數需要能夠正確處理一個或多個參數,我沒有嘗試正確編碼。

如果我像這樣運行它,我收到一個錯誤:

node.js:201
    throw e; // process.nextTick error, or 'error' event on first tick
          ^
TypeError: Cannot read property 'findOne' of undefined
    at /tmp/node_modules/mongoose/node_modules/hooks/hooks.js:27:28
    at /tmp/lib/api.js:227:12
    at Promise.<anonymous> (/tmp/lib/api.js:216:16)
    at Promise.<anonymous> (/tmp/node_modules/mongoose/lib/promise.js:120:8)
    at Promise.<anonymous> (events.js:67:17)
    at Promise.emit (/tmp/node_modules/mongoose/lib/promise.js:59:38)
    at Promise.complete (/tmp/node_modules/mongoose/lib/promise.js:70:20)
    at /tmp/node_modules/mongoose/lib/query.js:885:15
    at model.<anonymous> (/tmp/node_modules/mongoose/lib/document.js:181:5)
    at model.init (/tmp/node_modules/mongoose/lib/model.js:181:36)
# Run my function, do error handling, and run the callback if no error
runit = (func, args..., errmsg, callback) ->
  func args..., (err, docs) ->
    if err
      return console.log errmsg + ': ' + err
    callback docs

# Original code, simplified
vote = (res, data) ->
  runit Case.findOne { caseId: data.id }, 'Vote failed', (mycase) ->        
    myvote = new Vote
      case: mycase._id
    runit myvote.save, 'Could not add vote', ->   
      console.log 'Success!'

runit編譯為:

runit = function() {
  var args, callback, errmsg, func, _i;
  func = arguments[0], args = 4 <= arguments.length ? __slice.call(arguments, 1, _i = arguments.length - 2) : (_i = 1, []), errmsg = arguments[_i++], callback = arguments[_i++];
  return func.apply(null, __slice.call(args).concat([function(err, docs) {
    if (err) return console.log(errmsg + ': ' + err);
    return callback(docs);
  }]));
};

使用早期返回而不是條件分支,這樣可以使代碼簡單明了,並避免不必要的樣板代碼。

vote = (res, data) ->
  Case.findOne { caseId: data.id }, (err, mycase) ->
    return console.error 'Vote failed' if err?
    myvote = new Vote
      case: mycase._id
    myvote.save (err) ->
      return console.error 'Could not add vote' if err?
      console.log 'Success!'

我是Caolan異步庫的忠實粉絲。 所述庫的主要思想是每個回調的第一個參數是一個錯誤,如果沒有錯誤,則調用鏈中的下一個函數。 所以你可以看起來像這樣:

vote = (res, data) ->
  async.series [
    (next) -> Case.findOne { caseId: data.id }, next
    (next) -> myvote = new Vote({case: mycase_id}).save(next)
  ], (err, result) ->
    if err
      console.error err
    else
      console.log "Success!"

函數鏈在拋出的第一個錯誤時中斷,這樣您的最終回調實際上只負責處理單個錯誤。 這對於您想要暫停和報告遇到的第一個問題的串行進程非常有用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM