Don McCurdy Software Developer in Cambridge, MA.

Recent Posts

Using ES6 Generators with Callback-based Libraries

ES6 introduces generators (and yield expressions) to JavaScript. Kyle Simpson has written a nice introduction to generators, if you’re looking for more about how they work.

They’re a very welcome change from callbacks-of-infinite-sorrow situations, but generators aren’t necessarily well supported by most NPM packages. Which raises the question:

How do I use generators with callback-based libraries and older code?

I ran into this problem while trying out Koa (web framework, generators everywhere) and node-sqlite3 (database bindings with callbacks). Some NPM packages do come with generator support, but these are harder to find – and less likely to be stable – for a while yet. Let’s take some older code relying on callbacks and wire it up with a generator.

Here’s a basic fetch-things-from-a-database example:

var db = new ArbitraryDB();

var gizmoService = {
     * List all Gizmos.
    all: function () {
        db.all(function (error, result) {
            // [1] ???
        // [2] ???

// Application code. Let's protect this part from nasty callbacks.
var gizmos = gizmoService.all();
console.log(gizmos); // NULL

Well, that doesn’t work. We need to return a value at [2], but the callback at [1] hasn’t been invoked yet. Native Promises (not polyfills, unfortunately) can solve this problem.

NOTE: As of this writing, generators in NodeJS only work with the --harmony flag. I’m using NPM v0.12.0.

An updated example:

var db = new ArbitraryDB();

var gizmoService = {
     * List all Gizmos.
    all: function *() {
        // Return a new Promise
        return new Promise(function(resolve, reject) {
            db.all(function (error, result) {
                // ... and resolve or reject with callback result.
                if (error) {
                } else {

// Application code.
var gizmos = yield gizmoService.all();
console.log(gizmos); // [ ... gizmos ... ]

Or, to catch possible DB-level errors:

try {
    var gizmos = yield gizmoService.getAll();
} catch (error) {
    console.log('Oh, it broke.');

And that’s it! The rest of your application can continue without worrying about the callbacks tucked away in a dependency.


A short list of things I enjoy, to be updated at undisclosed and inconsistent intervals.


  • Sublime Text 3, with the Predawn theme and 30+ plugins, including GitGutter and SublimeLinter.
  • IA Writer, for writing anything that isn’t code.
  • Evernote, in place of web bookmarks.
  • Adobe Illustrator.


  • A Path Appears, Nicholas Kristof and Sheryl WuDunn.
  • The Sun Also Rises, Ernest Hemingway.
  • Frankenstein, Mary Shelley.
  • Eating Animals, Jonathan Safran Foer.
  • Anything I’m currently reading.


Grayscale CSS and Bookmarklet

A bit of code that can be used to convert any webpage (or part of a page) to grayscale. Because accessibility!


body {
  /* IE */
  filter: progid:DXImageTransform.Microsoft.BasicImage(grayscale=1);

  /* Chrome, Safari */
  -webkit-filter: grayscale(1);

  /* Firefox */
  filter: grayscale(1);


(function () {
  var body = document.body;['filter'] = 'progid:DXImageTransform.Microsoft.BasicImage(grayscale=1)';
  if (!['filter']) {['-webkit-filter'] = 'grayscale(1)';['filter'] = 'grayscale(1)';


javascript:(function(){var e=document.body;"progid:DXImageTransform.Microsoft.BasicImage(grayscale=1)",||(["-webkit-filter"]="grayscale(1)","grayscale(1)")}())