yui/yui3 — pull request #445 by juandopazo (2013-02-11 18:17:39+00:00)
Title: A+ compatible promises

This is a refactor of @lsmith's code in https://github.com/yui/yui3/pull/241. Previous discussions and the evolution of this code can be seen in https://github.com/juandopazo/yui3/pull/4.

This pull request introduces a new module called `promise` instead of `deferred`. Promises are already a complex concept to understand and teach, and deferred objects make it harder. This refactor internally keeps a similar relationship between objects as in deferreds+promises, but it tries to hide it with a new API.

The new way to create promises is by using the `Y.Promise` constructor and passing it a function in which you initialize promise. For example:

```JavaScript
/**
Waits for a number of milliseconds and returns a promise that gets
fulfilled when done waiting.

@param {Number} ms Number of milliseconds to wait
@return Promise
*/
Y.wait = function (ms) {
return new Y.Promise(function (fulfill) {
setTimeout(fulfill, ms);
});
};
```
Underneath there's another object called `Y.Promise.Resolver` which does the same thing as the old `Deferred`.

## A+ status
As far as interoperability goes the status of the A+ spec is very stable. There are other aspects that are still under discussion but are not essential to getting a compatible implementation. Mostly the A+ group is looking for the best API for creating promises and cancelling them. `new Y.Promise(fn)` was born in ]Microsoft's implementation for WinJS](http://msdn.microsoft.com/en-us/library/windows/apps/br211867.aspx) and mostly adopted by the A+ group, with some differences. This implementation follows the same pattern as the WinJS one.

Cancelling is a topic still under discussion and that it should at some point be added to the YUI implementation because some async operations are usually cancelled. For example: XHR and setTimeout.

## Tests
I've added tests that cover the basic functionality of promises, `when` and `batch`. Tests for `when` and `batch` should be enough, but the ones in the [A+ test suite](https://github.com/promises-aplus/promises-tests) are much more comprehensive. It'd be great to run them to the YUI test runs. They're written in Jasmine which doesn't help, but translating to YUI Test would double the effort or guarantee that they become outdated.

### Running the A+ Test Suite
Steps for running the test suite:
1. Create a folder somewhere
2. Copy the `package.json` file [that installs YUI and the tests](https://gist.github.com/juandopazo/4755591)
3. Copy the test adapter file (see the same gist), build the Promise module and point YUI in the adapter to the correct location of that module
4. Run `npm install .`
5. Run `npm test`

Can we add the A+ tests as a CLI test? What would it take?

## Docs
I'm starting to work on the docs. Nothing to see yet. I plan on:
* Covering some background on promises as simple async operations chaining, value wrappers and async control flow managers
* Showing how to create promises
* Explaining how `then`works, how to chain promises and deal with failures
* Explaining Y.when and Y.batch
* Adding at least two examples. A simple one like `Y.wait` and a more complex one like writing your own Y.Node plugin that chains transitions.