<!DOCTYPE html>
<html ng-app="app">
<head>
<script data-require="angular.js@*" data-semver="1.2.4" src="http://code.angularjs.org/1.2.4/angular.js"></script>
<script data-require="datejs@*" data-semver="0.1.0" src="//cdnjs.cloudflare.com/ajax/libs/datejs/1.0/date.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="AppCtrl">
<h1>{{title}}</h1>
Val A = {{valA}} <br />
Val B = {{valB}} <br />
Val C = {{valC}} <br />
<ul>
<li ng-repeat="line in log">{{line}}</li>
</ul>
</body>
</html>
// Code goes here
angular.module('app', []).controller('AppCtrl', function($scope, $q, $timeout) {
var delay = 1000,
throwStartA = false,
throwDoneA = true,
throwStartB = false,
throwDoneB = false,
recoverAtB = false,
propagateAtB = false;
$scope.title = "Promises, Promises!";
$scope.log = [];
function log(value){
$scope.log.push(new Date().toString('mm:ss') + ' - ' + value);
}
function GetValueA() {
var def = $q.defer();
log('Start A');
if (throwStartA) throw new Error('Start A');
$timeout(function() {
log('Done A');
try {
if (throwDoneA) throw new Error('Done A');
def.resolve('Value A');
}
catch(e) {
def.reject(e);
}
}, delay);
return def.promise;
}
function GetValueB() {
var def = $q.defer();
log('Start B');
if (throwStartB) throw new Error('Start B');
$timeout(function() {
log('Done B');
try {
if (throwDoneB) throw new Error('Done B');
def.resolve('Value B');
}
catch(e) {
def.reject(e);
}
}, delay * 2);
return def.promise;
}
function GetValueC() {
var def = $q.defer();
log('Start C');
$timeout(function() {
log('Done C');
def.resolve('Value C');
}, delay * 3);
return def.promise;
}
// when() returns a promise that is already resolved with a value of 'undefined'.
$q.when()
.then(function(){
// Now GetValueA() is inside a try/catch block because we called it inside then().
return GetValueA();
})
.then(function(val){ // success callback for promise returned by GetValueA
$scope.valA = val;
return GetValueB();
})
.then(function(val){ // success callback for promise returned by GetValueB
$scope.valB = val;
return GetValueC();
}, function(err){ // error callback for promise returned by GetValueB
log('Catch B - ' + err);
if (recoverAtB) {
return 'Recovered Value';
}
else if (propagateAtB) {
return $q.reject(err);
}
})
.then(function(val){ // then for promise returned by GetValueC
$scope.valC = val;
})
.catch(function(err){
log('Catch End - ' + err);
});
});
/* Styles go here */