There appear to be two routes we could take:
A) Simplistic. Implement a .then(resolvePromise, rejectPromise), which works like .response(resolvePromise) plus .error(rejectPromise)
This would not comply with the Promises/A+ .then(), but would be a “thenable” which interoperates.
B) Conformant. Implement a .then(resolvePromise, rejectPromise), which conforms to Promises/A+. Asyncs can go from fulfilled to rejected and vice versa, via .fail() and .recover. Thus, functions passed to resolvePromise and rejectPromise functions would need to be segregated from functions passed to response and error, and we’d need new logic: if onFulfilled is called onRejected must not be (and vice versa).
As I see it, Promises have three main advantages over Asyncs:
1) Exceptions thrown inside Promises cause the promise to be rejected.
2) Promise.all() and Promise.race() allow parallel executions
3) Familiarity for other Javascript programmers [eventually]
I think option A) is the sensible one. Implementing a conformant .then() doesn’t help with 1). IIRC, “thenables” may be passed to Promise.all(), so A) is just as good. (If Promise.all() only takes real Promises, Asyncs could be wrapped with a Promise.) With either option, we only get familiarity with .then(), not the rest of the Promise interface.
We don’t need to include a polyfill for Promises in Enyo; that’s actually orthogonal. I expect Enyo apps will start including
https://github.com/jakearchibald/es6-promise (I’ve already added it to Serene Notes.)
Apps could then update Enyo and add a Promise polyfill, then implement new code using Promises. As time for refactoring becomes available, old code could be refactored, replacing Asyncs with Promises, gaining the advantage of exception-catching and easier maintenance by programmers new to Enyo.