Don McCurdy Software Developer in Cambridge, MA.

Hi — I’m a developer at Google, currently working on Project Sunroof.

I love web development, design, and tools for understanding and visualizing data. Solutions for humanitarian and environmental issues are important to me. Let’s build something.

Recent Posts

What Can a Technologist Do About Climate Change

From an essay by Bret Victor (@worrydream), on how the tech community “can contribute to tech and/or policy solutions,” and why this is important —

You cannot calibrate your sense of what’s valuable and necessary to the current fashions in your field.

Climate change is the problem of our time. It’s everyone’s problem, but it’s our responsibility — as people with the incomparable leverage of being able to work magic through technology.

Read the full essay here. It’s excellent. I don’t mean to say that there aren’t other problems worth your time, but the general state of the tech community suggests we don’t value our time or energy highly enough.

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 the result.
                if (error) {
                    reject(error);
                } else {
                    resolve(result);
                }
            });
        });
    }
};

// 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.

Recommendations

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

Software

  • 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.

Books

  • 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.

Meta