kriskowal/q — pull request #327 by jlongster (2013-06-26 17:23:08+00:00)
Title: Support arrays and generators when using `yield`

A few really good ideas came out of the async discussions about generators a few weeks back. The best library I've seen yet is https://github.com/visionmedia/co, which implements them. Co allows you to use generators with raw `function(err, res) {}` style callbacks. Since it doesn't use promises it's quite limited though.

The coolest idea is to extend the handling of values produced by `yield`. The two cases I'd like to see are:

* If an array is yielded, wait on all elements in the array (exactly like Q.all(array))
* If a generator is yielded, automatically convert it into the `Q.async` runner and wait on it

This allows you to do some really succinct stuff:

```js
function* getTransaction(id) {
var trans = yield Transaction.find({ id: id });
trans.category = yield Category.find({ id: trans.categoryId });
return trans;
};

Q.spawn(function*() {
var ids = [1, 2, 3];
var transactions = yield ids.map(getTransaction);

// ...
});
```

Notice that `getTransaction` is just a normal generator function now, and it's expected to be called within `Q.spawn`. Additionally, an array of promises is yielded and the function waits for all of them to be fulfilled.

`Q.async` is still nice to library authors, but I think the above code is really nice for applications.

I realize there should be test cases and such but I wanted to vet this a little first.