( promise was fulfilled )
( promise was fulfilled )
(promise was rejected!)
// function somewhere in father-controller.js
var makePromiseWithSon = function() {
// This service's function returns a promise, but we'll deal with that shortly
SonService.getWeather()
// then() called when son gets back
.then(function(data) {
// promise fulfilled
if (data.forecast==='good') {
prepareFishingTrip();
} else {
prepareSundayRoastDinner();
}
}, function(error) {
// promise rejected, could log the error with: console.log('error', error);
prepareSundayRoastDinner();
});
}; app.factory('SonService', function ($http, $q) {
return {
getWeather: function() {
// the $http API is based on the deferred/promise APIs exposed by the $q service
// so it returns a promise for us by default
return $http.get('http://fishing-weather-api.com/sunday/afternoon')
.then(function(response) {
if (typeof response.data === 'object') {
return response.data;
} else {
// invalid response
return $q.reject(response.data);
}
}, function(response) {
// something went wrong
return $q.reject(response.data);
});
}
};
});console.log("1");
setTimeout(function(){console.log("2");},3000);
console.log("3");
setTimeout(function(){console.log("4");},1000);Javascript executes each line in sequence.
So you told js:
write 1: js writes 1
wait 3 seconds and then write 2: ok I'll wait 3 seconds...now what?
write 3: ok I'll write 3, by the way, the 3 seconds is not up.
wait 1 second and then write 4: ok I'll wait 1 second...
then js waits .99999 seconds ... and writes 4
then waits some more and writes 2
We need promises because we need to make decisions based on the possible results of our call
better die.......
var deferred=$q.defer();var deferred = $q.defer();
// deferred contains the promise to be returned
// to resolve (fulfill) a promise use .resolve
deferred.resolve(data);
// to reject a promise use .reject
deferred.reject(error);// this
$http.get('/api/v1/movies/avengers')
.success(function(data, status, headers, config) {
$scope.movieContent = data;
});
// is the same as
var promise = $http.get('/api/v1/movies/avengers');
promise.then(
function(payload) {
$scope.movieContent = payload.data;
});angular.module('atTheMoviesApp', [])
.controller('GetMoviesCtrl',
function($log, $scope, movieService) {
$scope.getMovieListing = function(movie) {
var promise =
movieService.getMovie('avengers');
promise.then(
function(payload) {
$scope.listingData = payload.data;
},
function(errorPayload) {
$log.error('failure loading movie', errorPayload);
});
};
})
.factory('movieService', function($http) {
return {
getMovie: function(id) {
return $http.get('/api/v1/movies/' + id);
}
}
});separation of concerns
...
.factory('movieService', function($http, $log, $q) {
return {
getMovie: function(movie) {
var deferred = $q.defer();
$http.get('/api/v1/movies/' + movie)
.success(function(data) {
deferred.resolve({
title: data.title,
cost: data.price});
}).error(function(msg, code) {
deferred.reject(msg);
$log.error(msg, code);
});
return deferred.promise;
}
}
});this.getMovie = function(movie) {
return $http.get('/api/v1/movies/' + movie)
.then(
function (response) {
return {
title: response.data.title,
cost: response.data.price
});
},
function (httpError) {
// translate the error
throw httpError.status + " : " +
httpError.data;
});
};...and now the error returned will be a single string, not the $http error with data, status, headers and config properties.
$q.all lets you trigger several callbacks at the same time, and use a single then function to join them all together.
service('asyncService', function($http, $q) {
return {
loadDataFromUrls: function(urls) {
var deferred = $q.defer();
var urlCalls = [{ url: 'ajax1.html' },{ url: 'ajax2.html' },{ url: 'ajax3.html' }];
angular.forEach(urls, function(url) {
urlCalls.push($http.get(url.url));
});
// they may, in fact, all be done, but this
// executes the callbacks in then, once they are
// completely finished.
$q.all(urlCalls)
.then(
function(results) {
deferred.resolve(
JSON.stringify(results))
},
function(errors) {
deferred.reject(errors);
},
function(updates) {
deferred.update(updates);
});
return deferred.promise;
}
};
});