Practical JS promises github.com/asakusuma/promise-workshop Asa Kusuma
Async operations are 1st class citizens, represented as objects
var loadContainer = showPage('#photo-view'); var loadController = Controller.load(id, authToken); ! Promises.all([ loadContainer, loadController ]).then(Controller.pageDidLoad) .then(null, handleError); ! loadController.then(null, handleError);
pageDidLoad: function(results) { var loadContainerResult = results[0]; var loadControllerResult = results[1]; }
load: function(id, authToken) { return DataStore.get(id, authToken) .then(_.bind(this.display, this)); }
Compose functions without introducing coupling to the functions themselves
Promise handlers accept a single parameter
Functional Programming • Input arguments • Do operations • Return result • Avoid state • Avoid mutation • Avoid side-effects
The A+ Spec • 3 states: pending, fulfilled, rejected (settled*) • .then(), which takes handler functions as params • Can call multiple times; attach multiple handlers • Handler called even if then() called after settled • Once fulfilled or rejected, cannot change state
Pending Fulfilled Rejected Settled onFulfilled() onRejected()
.then(onFulfill, onReject) • onFulfill called when promise is fulfilled • onReject called when promise is rejected • Return val becomes promise returned by then()*** • Handler execution deferred to nextTick
fulfilledPromise .then(function(){ console.log(‘world!’); }); console.log(‘Hello, ’);
Promise lingo • Handler parameter • Fulfillment value • Rejection reason • Resolved == settled
Error handling • Error in onFulfill will reject returned promise • Throwing rejects next promise in chain • Non A+ features • Long stack traces • Global error listener
myPromise.then( handleSuccess, handleError );
myPromise.then( handleSuccess, handleError ).then(null, handleError);
How are promises created?
Closure Syntax var myPromise = new Promise(function(f, r) { setTimeout(function() { f(‘Hello world’); }, 500); });
Deferred Syntax var d = RSVP.defer(); ! setTimeout(function() { d.resolve(‘Hello world’); }, 500); ! var myPromise = d.promise;
var partialLoad = promises.defer(); … view.on(‘renderPartial’, function() { partialLoad.fulfill($el); }); … return partialLoad.promise;
view.on(‘renderPartial’, _.partial(partialLoad.fulfill, $el));
Deferreds are the read-write parent of the read-only promise
Exercise Creating Promises
getMessage: function(callback) ! RSVP.defer() new RSVP.Promise(function(f, r) { … })
Async or sync? Promise don’t care
createContext() .then(fetchUser) .then(initializeRouters) .then(initializeBindings)
Use promises to wrap any potentially non-blocking code
Common uses of promises • Data retrieval • Anything involving an external call • Loading CSS • Animation • Template rendering
Promise vs Event vs Stream • Promises are for operations executed once • Events and streams are for repeated events • Promises and streams are both object-based
High-order functions • Functions that input and/or output functions • Examples • _.partial(func, arg) • _.bind(func, context) • Very useful with promises
Using a high order function myPromise .then(generateSumPartial(5)) .then(output)
The high order function function generateSumPartial(n) { return function(resolutionValue) { return n + resolutionValue; } }
Exercise Advanced Chaining
Promise Libraries • Promise creation • Promise inspection • Utility functions • Error handling • Native vs. Library
Utility Functions • .all()/allSettled() • .hash() • .spread() • .map() • Static vs member functions
Where jQuery will $@#% you $.ajax() .then(onFulfill, onReject) .then(output, errorPage);
Testing • .then() handler always on nextTick • Most tests assume synchronous • sinon.stub(process, ‘nextTick’).yields(); • Use the it() callback done handler
it(‘should blah’, function(done) { testThis.then(function(result) { expect(result).to.be.ok(); done(); }).then(null, done); });
Questions? github.com/asakusuma/promise-workshop akusuma@linkedin.com

Practical JavaScript Promises