var app = angular.module('plunker', ['ui.bootstrap']);

app.controller('MainCtrl', function($scope, $q) {
    $scope.text = '';
    $scope.chain = false;
    $scope.progressbars = [];
    $scope.useQ = false;
    var count = 1;
    var currentPromise = null;
    
    var defer = function() {
        return $scope.useQ ? Q.defer() : $q.defer();
    };
    
    var getPromise = function(forceFailure) {
        var deferred = defer();
        var count = 1;
        var timeoutID = setInterval(function() {
            deferred.notify(count++);
            if (count > 10) {
                clearInterval(timeoutID);
                if (forceFailure) {
                    deferred.reject();
                }
                else {
                    deferred.resolve();
                }
            }
        }, 100 + Math.floor((Math.random() * 500)));
        
        return deferred.promise;
    };
    
    var printPromise = function(id, forceFailure) {
        return getPromise(forceFailure).then(function() {
            $scope.text += 'Success: ' + id + '\n';
        }, function() {
            $scope.text += 'Failed:  ' + id + '\n';
            throw new Error(id + ' Failed');
        });
    };
    
    var connectProgressBar = function(bar, promise) {
        var removeBar = function() {
            var index = $scope.progressbars.indexOf(bar);
            if (index >= 0) {
                $scope.progressbars.splice(index, 1);
            }
        };
        
        return promise.then(null, null, function(progress) {
            bar.message = (progress / 10 * 100) + '%';
            bar.progress = progress;
        }).finally(removeBar);
    };
    
    var addProgressBar = function(id, type) {
        var bar = {id: id, progress: 0, message: 'waiting', type: type};
        $scope.progressbars.push(bar);
        return bar;
    };
    
    var addPromise = function(forceFailure) {
        var type = forceFailure ? 'danger' : 'success';
        var bar = addProgressBar(count, type);
        var promise = printPromise(count++, forceFailure);
        return connectProgressBar(bar, promise);
    };
    
    var addChainedPromise = function(forceFailure) {
        var oldCount = count++;
        var type = forceFailure ? 'danger' : 'success';
        var bar = addProgressBar(oldCount, type);
        
        return function() {
            var promise = printPromise(oldCount, forceFailure);
            return connectProgressBar(bar, promise);
        };
    };
    
    $scope.launchPromise = function(forceFailure) {
        if ($scope.chained && currentPromise) {
            currentPromise = currentPromise.then(addChainedPromise(forceFailure));
        }
        else {
            currentPromise = addPromise(forceFailure);
        }
    };
    
    $scope.clear = function() {
        currentPromise = null;
        $scope.progressbars.length = 0;
        count = 1;
        $scope.text = '';
    };
});
<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <link data-require="bootstrap-css@3.0.3" data-semver="3.0.3" rel="stylesheet" href="http://getbootstrap.com" />
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="angular.js@1.2.x" src="https://code.angularjs.org/1.3.0-beta.5/angular.js" data-semver="1.3.0-beta.5"></script>
    <script data-require="angular-ui-bootstrap@0.10.0" data-semver="0.10.0" src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.10.0.min.js"></script>
    <script data-require="q.js@1.0.0" data-semver="1.0.0" src="//cdnjs.cloudflare.com/ajax/libs/q.js/1.0.0/q.min.js"></script>
    <link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet" />
    <script src="app.js"></script>
  </head>

  <body ng-controller="MainCtrl">
    <div class="spacing">
      <div class="btn-group">
        <label class="btn btn-primary" ng-model="useQ" btn-radio="false">$q</label>
        <label class="btn btn-primary" ng-model="useQ" btn-radio="true">Q</label>
      </div>
      Chained: <input type="checkbox" ng-model="chained" />
    </div>
    <div class="spacing">
      <button ng-click="launchPromise()">Success</button>
      <button ng-click="launchPromise(true)">Fail</button>
      <button ng-click="clear()">Clear</button>
    </div>
    <div class="spacing">
      <textarea ng-model="text"></textarea>
    </div>
    <div ng-repeat="bar in progressbars">
      <progressbar max="10" value="bar.progress" type="{{bar.type}}">
        <span style="color:black; white-space:nowrap;">{{bar.id}}: {{bar.message}}</span>
      </progressbar>
    </div>
  </body>

</html>
/* Put your css in here */

.spacing {
    margin: 5px;
}

div > textarea {
    width: 100%;
    height: 300px;
}