Chaining promises with AngularJs and JQuery
Promises allow for consistent handling of the results of a task (Usually asynchronous). A promise is returned from a function call with a deferred result.
The promise result is either success (promise.resolve) or failure (promise.reject).
The basic usage pattern looks like this:
If you must have more than one step then promises can be chained. Each step in the chain should return another promise. If any of the steps get rejected then the next steps are skipped and the next rejection handler is called.
Use 'catch' to make it more obvious when the failure handling is.
'finally' indicates a step which always runs.
Use 'done' to execute code when no rejections occur.
Use 'fail' to make it obvious when the failure handling is.
'always' indicates a step which always runs.
Avoiding easy mistakes:
1. Forgetting to include the return keyword.
In this case when doStuff1() is resolved doStuff2() will be called.
Because it does not return a promise then doStuff3() will be called irrespective to the result of doStuff2()
unless it throws an exception.
i.e. A step must return a promise or throw an exception otherwise the next 'resolved' step will be called.
2. In AngularJs handling failure on every chained step rather than once at the end.
If a step should only execute if the previous step was resolved then rejection should be handled after the last step.
The problem with handling it in each 'then' is that if the rejection function does not either return a promise which is rejected or throw an exception then the next chained resolved step will be executed.
e.g. if doStuff1() is rejected then 'alert('step 1 was rejected');' will be executed. Because this does not return a promise the next 'then' statement resolved step will run and 'doStuff3()' will be called.
Note: this is different to the way JQuery works. It will pass the rejected promise to the next '.then' causing each rejection handler to be called.
JQuery Chained Promise Example: http://jsfiddle.net/2DQwx/