<!DOCTYPE html>
<html>

  <head>
    <script data-require="angular.js@*" data-semver="1.3.0-beta.5" src="https://code.angularjs.org/1.3.0-beta.5/angular.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.min.js"></script>
    <link rel="stylesheet" href="style.css" />
    <link href='http://fonts.googleapis.com/css?family=Droid+Sans:700' rel='stylesheet' type='text/css'>
    <script src="app.js"></script>
    <script src="controllers.js"></script>
    <script src="utils.js"></script>
  </head>

  <body>
    <div id="container">
      <h1 id="status" ui-view="viewA"></h1>
    </div>
    <script>
    
      // Example by: Jim Cummins (Twitter: @jimforcy, Github: jcummins)
      // 
      // For more information, see README.md
      
      // Set initial status to red before we go ahead
      updateStatus('Before async.', '#C91818');
      
      // Get angular
      var $ng = angular.injector(['ng']);
      
      // Get the $q service from angular to use deferreds
      var $q = $ng.get('$q');
      
      function fakeAsyncCallMaker(html, color) {
          // In this example we only use one fake async function, 
          // but in reality we could use multiple aync functions, 
          // all returning promises then we could use $q.all
          // to ensure that all resolve before we move on to
          // bootstrapping angular.
          var deferred = $q.defer();
          
          // An example of an artificially slow async function that will
          // resolve the deferred at some point (random time between 1 
          // and 2 seconds from now). Obviously this would be an actual
          // async call in an app
          window.setTimeout(function() {
              updateStatus(html, color);
              deferred.resolve();
          }, Math.floor(Math.random() * 3000) + 2000);
    
          // Return the promise immediately, eventually the
          // deferred will be resolved, once async is done
          return deferred.promise;
      };
      
      // Use $q to resolve every promise returned from an array
      // of functions before we actually bootstrap. Here we only
      // use one async call as an example.
      $q.all([
        fakeAsyncCallMaker('After async. <br>Before bootstrap.','#1A3457')
        // , fakeAsyncCallMaker2
        // , fakeAsyncCallMaker3
        // etc....
      ]).then(function () {
        window.setTimeout(function() {
          angular.bootstrap(document, ['plunker']);
          updateStatus('After bootstrap. Before view.', '#ED7834');
        }, Math.floor(Math.random() * 3000) + 2000);
      });
    </script>
  </body>

</html>
// Code goes here

angular.module('plunker',['ui.router','plunker.controllers'])

.config(function($stateProvider, $urlRouterProvider, $httpProvider) {

  $urlRouterProvider.otherwise('/');
    
  // the shift tab has its own child nav-view and history
  $stateProvider
  .state('test', {
    url: '/',
    views: {
      "viewA": {
        templateUrl: 'test.html',
        controller: 'TestCtrl'
      }
    },
    // This is an artificial pause before the view is shown.
    // Normally bootstrap happens and view is rendered so quickly
    // That we'd never see it.
    resolve: {
      testResolver: ['$q', function($q){
        var deferred = $q.defer();
        window.setTimeout(function() {
            updateStatus(undefined, '#008C39');
            deferred.resolve();
        }, Math.floor(Math.random() * 3000) + 2000);
        return deferred.promise;
      }]
    }
  });
  
});
/* Styles go here */
body {
  background-color:#C91818;
}
h1 {
  font-family: 'Droid Sans', sans-serif;
  color: #fff;
  text-transform:uppercase;
}

a {
  color: #FCDE5B;
}

#container {
  padding:20px;
  top:0;
  bottom:0;
  left:0;
  right:0;
  position:absolute;
  margin:auto;
  height:200px;
  width:200px;
  /* Fallback for web browsers that don't support RGBa */
    background-color: rgb(0, 0, 0);
    /* RGBa with 0.6 opacity */
    background-color: rgba(0, 0, 0, 0.3);
}
Example by: Jim Cummins (Twitter: @jimforcy, Github: jcummins)
 
Background issue: https://github.com/rev087/ng-inspector/issues/2

My particular use case: I use this method to seed data into my app. Since I wouldn't want see data to be hard coded into my app, it makes sense for it to happen before Angular is even loaded. Thus it makes sense to add seed data to localstorage before bootstrapping so that I can illustrate how an existing user with past user data might experience the application.

This is a visual representation of that process.
// Utility function for this example.
// Update the page as we show the various parts of the run
// up to bootstrapping.
function updateStatus(html, color) {
  
    if(typeof html !== 'undefined') 
    {
      document.getElementById('status').innerHTML=html;
      var div = document.createElement("div");
      div.innerHTML = html;
      var text = div.textContent || div.innerText || "";
      console.log(text);
    }
    
    if(typeof color !== 'undefined') 
    {
      document.body.style.backgroundColor = color;
    }
    
}
angular.module('plunker.controllers',[])

.controller('TestCtrl', function($scope, $rootScope) {
  window.setTimeout(function() {
    updateStatus('I am the view! <br><br><a href="javascript:location.reload();">Repeat?</a>');
  }, Math.floor(Math.random() * 1000) + 1500);
});
I am the view!