A promise represents a deferred execution of an asynchronous operation. Promises allow functions to write asynchronous code that looks synchronous by using the .then() method to specify callbacks. The .then() method can return data immediately, return a new promise, or return a rejection. Errors can be handled using .catch(), and multiple concurrent promises can be combined with $q.all(). Finally, promises provide a consistent way to handle both success and failure cases for asynchronous code.
1. $q: how to keep promises with AngularJS
Dominique Dumont
Apr 2018
Dominique Dumont $q promises
2. What is a promise ?
A way to write a function whose execution is deferred
A way to trigger its execution on an external event
Caveat
This presentation was prepared in 2015 for Angular 1.5. Even if $q
is obsolete now, the techniques shown in this slideset can be
applied to other promises libraries like q or bluebird
Dominique Dumont $q promises
3. When is a promise needed ?
remote service call (Ajax call through $http service)
timer ($timeout service)
user interaction
wrap an old style API
Dominique Dumont $q promises
4. How to use a promise
$http.get('http://foo.com/')
.then(function(response) {
// extract data from response
return data;
})
.catch(function(error) {
// handle error, we'll see what to return later
})
.finally(function() {
$log.log(all done);
});
Dominique Dumont $q promises
5. then can be chained
Immediate calls:
var getData = $http.get('http://foo.com/')
.then(function(response) {
return $response.data.stuff;
})
.then(function(stuff) {
// do something with stuff
});
Dominique Dumont $q promises
6. then can be cascaded
Asynchronous calls:
var getData = $http.get('http://foo.com/')
.then(function(fooResponse) {
// need further remote request
// return a new promise
return $http.get('http://bar.com/');
})
.then(function(barResponse) {
// extract data
return data;
});
Dominique Dumont $q promises
7. then can throw error
var getData = $http.get('http://foo.com/')
.then(function(fooResponse) {
// $http call returned 200, but...
return $q.reject(I'm not happy);
});
Dominique Dumont $q promises
8. then summary
Promise callback can perform 3 types of treatment:
1 Immediate: return data
2 Asynchronous: return a new promise
3 Rejection: return $q.reject() with a message
Dominique Dumont $q promises
9. Error handling
then and catch behave like try and catch:
$http.get() // blow
.then(doA) // skip
.then(doB) // skip
.catch(cleanUp) // run
.then(doC) // run
.finally(allDone); // run
Dominique Dumont $q promises
10. Error handling
then and catch behave like try and catch:
$http.get() // ok
.then(doA) // $q.reject
.then(doB) // skip
.catch(cleanUp) // run
.then(doC) // run
.finally(allDone); // run
Dominique Dumont $q promises
11. Error handling
then and catch behave like try and catch:
$http.get() // blow
.then(doA) // skip
.then(doB) // skip
.catch(cleanUp) // blow
.then(doC) // skip
.finally(allDone); // run
nally() is run in all cases
Dominique Dumont $q promises
12. Concurrent promises
Anonymous:
$q.all([ getFoo, getBar ])
.then(function(res) {
var foo = res[0];
var bar = res[1];
});
Named:
$q.all({ 'foo': getFoo, 'bar': getBar ])
.then(function(res) {
var foo = res['foo'];
var bar = res['bar'];
});
Dominique Dumont $q promises
13. Concurrent promises
Anonymous:
$q.all([ getFoo, getBar ])
.then(function(res) {
var foo = res[0];
var bar = res[1];
});
Named:
$q.all({ 'foo': getFoo, 'bar': getBar ])
.then(function(res) {
var foo = res['foo'];
var bar = res['bar'];
});
Dominique Dumont $q promises
14. Concurrent promises and error handling
Any error is trapped in $q.all.catch():
var getFoo = $http.get(fooUrl).then(extract);
var getBar = $http.get(barUrl).then(extract);
$q.all({ 'foo': getFoo, 'bar': getBar })
.then(handleFooBar)
.catch(cleanUp); // receive data from failed promise
Dominique Dumont $q promises