Hacker News new | ask | show | jobs
by amadiver 5636 days ago
`Bind` with named methods goes a long way to cleaning up nested callbacks. Here's a (quick+dirty; I know I'm missing some `do`'s in there) version of the same code in CoffeeScript:

  _ =
    fileMenu: ->
      mainWindow.menu "File", (e,f) => this.onFile(e,f)

    onFile: (err,file) -> 
      if err then throw err
      file.openMenu (e,m) => this.onOpenMenu(e,m)

    onOpenMenu: (err,menu) ->
      if err then throw err
      menu.item "Open", (e,i) => this.onOpen(e,i)
  
    onOpen: (err,item) ->
      if err then throw err
      mainWindow.getChild type('Window'), (e,d) => this.onDialog(e,d)

    onDialog: (err,dialog) ->
      if err then throw err
      #...

  _.fileMenu()
( `=>` is CoffeeScript for a function bound to the current scope )
1 comments

We've adopted a way that allows us to do basically this:

    mainWindow.menu "File", (err, file)->
        openMenu err, (err, menu)->
            getItem err, "Open", (err, item)->
                click err, item, (err)->
                    getChild err, getChildType("Window"), (err, dialog)->
                        if err? and err instanceof NoFileError
                            # do stuff
                        if err? and err instanceof InvalidClickError
                            # do other stuff
                        if err?
                            throw err
                        # do stuff with dialog if no err
                        
Each function takes as first argument an error and as last a callback. If there's an error, the function just passes the error up the callback stack until it gets dealed with.

    fun = (err, args..., callback)
You can't pull that off if your code is heavily object oriented though:

    mainWindow.menu "File", (err, file)->
        # If mainWindow.menu errors, file is undefined 
        # and the call to openMenu throws an error
        file.openMenu err, (err, menu)-> 
            # ...
Breaking your code/api up with modules instead into classes fixes that.