heapwolf/blog

Asynchronous flow control using generators and destructuring

heapwolf opened this issue · 0 comments

Two of my favorite things to come out of es6 were destructuring, an expression that makes it possible to extract data from arrays or objects into distinct variables 1 and generators, functions which can be exited and later re-entered 2. Together these two features can flatten asynchronous flow control.

const { run, wrap } = require('yl')
const fs = wrap(require('fs'))
const assert = require('assert')

run(function* () {

  const [statError, s] = yield fs.stat('./index.js')
  const [readError, f] = yield fs.readFile('./index.js')

  assert.equal(f.length, s.size)
})

The above code uses a tiny library called yl. You could write this yourself easily in under 15 lines of code. If you can make it smaller, send me a pull request! The really nice thing about this code is that you can use it today without the need for a massive tool chain or huge compiler like babel.

You already know about calback hell. But for context, here is the es5 version.

var yl = require('yl')
var run = yl.run
var wrap = yl.wrap
var fs = wrap(require('fs'))
var assert = require('assert')

fs.stat('./index.js', function (statError, s) {
  fs.readFile('./index.js', function (readError, f) {
    assert.equal(f.length, s.size)
  })
})