Asynchronous Array Mapping in Ruby

Posted 14 Mar 2013 to ruby, eventmachine and has Comments

EventMachine is great, but may require a few fights to get started.

Recently, I wanted to be able to get the sizes of each image in an array using FastImage. It’s fast, but it’s not that fast when you’ve got tens or hundreds of images you’re trying to size at once.

What I needed was an asynchronous map method for Arrays, like this:

images = [ "", "", ... ]
images.async_map { |img| FastImage.size(img) }

EventMachine did not make this easy. After some fighting, here’s what I came up with:

class Array
  def async_map(&block)
    results = nil do
      operation = proc { |item, iter|
        EventMachine.defer(proc { }, proc { |r| iter.return(r) })
      callback = proc { |rs|
        results = rs
      }, length).map(operation, callback)

It works (10x speed increase!), but I’d like to believe that there’s got to be an easier way to do this.