Coffescript和Nodejs关于回调的编码风格



让我们开门见山。我喜欢CS,我喜欢node,正如上帝所建议的那样,我可以很好地使用回调。

不幸的是,我通常会在稍微嵌套的回调中不断地检查错误。

下面是三种不同的样式来完成相同的示例任务。哪一个可以避免缩进和条件地狱,同时又不牺牲可读性?

如果不使用promise、async或iced cs,请随时建议新的。

authenticate: (token, cb) =>
  @collection 'services', (err, collection) =>
    if err
      cb err, undefined
    else
      collection.findOne token: token, (errFindingService, service) =>
        if err
          cb errFindingService, undefined
        else
          cb undefined, service
authenticate: (token, cb) =>
  @collection 'services', (err, collection) =>
    if not err
      collection.findOne token: token, (errFindingService, service) =>
        if not errFindingService
          cb undefined, service
        else
          cb errFindingService, undefined
    else
      cb err, undefined
authenticate: (token, cb) =>
  @collection 'services', (err, collection) =>
    return cb err, undefined if err
    collection.findOne token: token, (errFindingService, service) =>
      return cb errFindingService, undefined if err
      cb undefined, service

PS:在第二个问题上,我使用if not err而不是unless来符合https://github.com/polarmobile/coffeescript-style-guide

提前感谢大家。^_^

CoffeeScript中错误处理的首选样板是return callback error if error。所以

queryDb conditions, (error, results) ->
  return callback error if error
  console.log result for result in results
  • 这是一个1行
  • 我强烈希望错误处理始终处于顶部,并使用return短路逻辑
  • 这使得成功代码处于相同的缩进级别,而不是执行if/else

第一个更接近nodejs内部使用的内容,例如在fs模块中。

err是第一个参数,因此首先检查它是有意义的。一旦它让开,它就会"向下钻"到回调堆栈中。

除了显式返回之外,第一个和第三个选项编译为相同的JS。

哪一个更容易阅读和识别关键部分?考虑一下几个月后查看代码。

来自Python背景,我更喜欢使用更开放的结构(例如第一个),除非更紧凑的形式更清晰。因此,虽然我喜欢Coffeescapet理解,但我不太喜欢省略所有可能的{}()的表达式。如果我不得不停下来,在脑海中再加上这些,简洁就太过分了。

使用平面流,它可以看起来像这样:

{ flow } = require 'flat-flow' 
authenticate: (token, done) ->
  flow { getCollection: @collection }, [
    # Get collection.
    (done) ->
      @getCollection 'services', (err, collection) ->
        done err, { collection }
    # Get service
    (done) ->
      @collection.findOne { token }, (err, service) ->
        done err, { service }
    # # Get service (alternative)
    # (done, { collection }) ->
    #   collection.findOne { token }, (err, service) ->
    #     done err, { service }
  ], (err, { service }) ->
    done err, service
    # You can use @service as well.

它在长调用链上仍然是干净的(带或不带条件词)。

最新更新