@@ -299,14 +299,18 @@ function qFactory(nextTick, exceptionHandler, errorOnUnhandledRejections) {
* @returns {Deferred } Returns a new instance of deferred.
*/
function defer ( ) {
var d = new Deferred ( ) ;
//Necessary to support unbound execution :/
d . resolve = simpleBind ( d , d . resolve ) ;
d . reject = simpleBind ( d , d . reject ) ;
d . notify = simpleBind ( d , d . notify ) ;
return d ;
return new Deferred ( ) ;
}
function Deferred ( ) {
var promise = this . promise = new Promise ( ) ;
//Non prototype methods necessary to support unbound execution :/
this . resolve = function ( val ) { resolvePromise ( promise , val ) ; } ;
this . reject = function ( reason ) { rejectPromise ( promise , reason ) ; } ;
this . notify = function ( progress ) { notifyPromise ( promise , progress ) ; } ;
}
function Promise ( ) {
this . $$state = { status : 0 } ;
}
@@ -316,13 +320,13 @@ function qFactory(nextTick, exceptionHandler, errorOnUnhandledRejections) {
if ( isUndefined ( onFulfilled ) && isUndefined ( onRejected ) && isUndefined ( progressBack ) ) {
return this ;
}
var result = new Deferred ( ) ;
var result = new Promise ( ) ;
this . $$state . pending = this . $$state . pending || [ ] ;
this . $$state . pending . push ( [ result , onFulfilled , onRejected , progressBack ] ) ;
if ( this . $$state . status > 0 ) scheduleProcessQueue ( this . $$state ) ;
return result . promise ;
return result ;
} ,
'catch' : function ( callback ) {
@@ -338,34 +342,27 @@ function qFactory(nextTick, exceptionHandler, errorOnUnhandledRejections) {
}
} ) ;
//Faster, more basic than angular.bind http://jsperf.com/angular-bind-vs-custom-vs-native
function simpleBind ( context , fn ) {
return function ( value ) {
fn . call ( context , value ) ;
} ;
}
function processQueue ( state ) {
var fn , deferred , pending ;
var fn , promise , pending ;
pending = state . pending ;
state . processScheduled = false ;
state . pending = undefined;
try {
for ( var i = 0 , ii = pending . length ; i < ii ; ++ i ) {
state . pur = true ;
deferred = pending [ i ] [ 0 ] ;
promise = pending [ i ] [ 0 ] ;
fn = pending [ i ] [ state . status ] ;
try {
if ( isFunction ( fn ) ) {
deferred . resolve ( fn ( state . value ) ) ;
resolvePromise ( promise , fn ( state . value ) ) ;
} else if ( state . status === 1 ) {
deferred . resolve ( state . value ) ;
resolvePromise ( promise , state . value ) ;
} else {
deferred . reject ( state . value ) ;
rejectPromise ( promise , state . value ) ;
}
} catch ( e ) {
deferred . reject ( e ) ;
rejectPromise ( promise , e ) ;
}
}
} finally {
@@ -401,83 +398,80 @@ function qFactory(nextTick, exceptionHandler, errorOnUnhandledRejections) {
nextTick ( function ( ) { processQueue ( state ) ; } ) ;
}
function Deferred ( ) {
this . promise = new Promise ( ) ;
function resolvePromise ( promise , val ) {
if ( promise . $$state . status ) return ;
if ( val === promise ) {
$$reject ( promise , $qMinErr (
'qcycle' ,
'Expected promise to be resolved with value other than itself \'{0}\'' ,
val ) ) ;
} else {
$$resolve ( promise , val ) ;
}
}
extend ( Deferred . prototype , {
resolve : function ( val ) {
if ( this . promise . $$state . status ) return ;
if ( val === this . promise ) {
this . $$reject ( $qMinErr (
'qcycle' ,
'Expected promise to be resolved with value other than itself \'{0}\'' ,
val ) ) ;
function $$resolve ( promise , val ) {
var then ;
var done = false ;
try {
if ( isObject ( val ) || isFunction ( val ) ) then = val . then ;
if ( isFunction ( then ) ) {
promise . $$state . status = - 1 ;
then . call ( val , doResolve , doReject , doNotify ) ;
} else {
this . $$resolve ( val ) ;
}
} ,
$$resolve : function ( val ) {
var then ;
var that = this ;
var done = false ;
try {
if ( isObject ( val ) || isFunction ( val ) ) then = val . then ;
if ( isFunction ( then ) ) {
this . promise . $$state . status = - 1 ;
then . call ( val , resolvePromise , rejectPromise , simpleBind ( this , this . notify ) ) ;
} else {
this . promise . $$state . value = val ;
this . promise . $$state . status = 1 ;
scheduleProcessQueue ( this . promise . $$state ) ;
}
} catch ( e ) {
rejectPromise ( e ) ;
promise . $$state . value = val ;
promise . $$state . status = 1 ;
scheduleProcessQueue ( promise . $$state ) ;
}
} catch ( e ) {
doReject ( e ) ;
}
function resolvePromise ( val ) {
if ( done ) return ;
done = true ;
that . $$resolve ( val ) ;
}
function rejectPromise ( val ) {
if ( done ) return ;
done = true ;
that . $$reject ( val ) ;
}
} ,
function doResolve ( val ) {
if ( done ) return ;
done = true ;
$$resolve ( promise , val ) ;
}
function doReject ( val ) {
if ( done ) return ;
done = true ;
$$reject ( promise , val ) ;
}
function doNotify ( progress ) {
notifyPromise ( promise , progress ) ;
}
}
reject : function ( reason ) {
if ( this . promise . $$state . status ) return ;
this . $$reject ( reason ) ;
} ,
function rejectPromise ( promise , reason ) {
if ( promise . $$state . status ) return ;
$$reject ( promise , reason ) ;
}
$$reject : function ( reason ) {
this . promise . $$state . value = reason ;
this . promise . $$state . status = 2 ;
scheduleProcessQueue ( this . promise . $$state ) ;
} ,
function $$reject ( promise , reason ) {
promise . $$state . value = reason ;
promise . $$state . status = 2 ;
scheduleProcessQueue ( promise . $$state ) ;
}
notify : function ( progress ) {
var callbacks = this . promise . $$state . pending ;
if ( ( this . promise . $$state . status <= 0 ) && callbacks && callbacks . length ) {
nextTick ( function ( ) {
var callback , result ;
for ( var i = 0 , ii = callbacks . length ; i < ii ; i ++ ) {
result = callbacks [ i ] [ 0 ] ;
callback = callbacks [ i ] [ 3 ] ;
try {
result . notify ( isFunction ( callback ) ? callback ( progress ) : progress ) ;
} catch ( e ) {
exceptionHandler ( e ) ;
}
function notifyPromise ( promise , progress ) {
var callbacks = promise . $$state . pending ;
if ( ( promise . $$state . status <= 0 ) && callbacks && callbacks . length ) {
nextTick ( function ( ) {
var callback , result ;
for ( var i = 0 , ii = callbacks . length ; i < ii ; i ++ ) {
result = callbacks [ i ] [ 0 ] ;
callback = callbacks [ i ] [ 3 ] ;
try {
notifyPromise ( result , isFunction ( callback ) ? callback ( progress ) : progress ) ;
} catch ( e ) {
exceptionHandler ( e ) ;
}
} ) ;
}
}
} ) ;
}
} ) ;
}
/**
* @ngdoc method
@@ -516,9 +510,9 @@ function qFactory(nextTick, exceptionHandler, errorOnUnhandledRejections) {
* @returns {Promise } Returns a promise that was already resolved as rejected with the `reason`.
*/
function reject ( reason ) {
var result = new Deferred ( ) ;
result . reject ( reason ) ;
return result . promise ;
var result = new Promise ( ) ;
rejectPromise ( result , reason ) ;
return result ;
}
function handleCallback ( value , resolver , callback ) {
@@ -556,9 +550,9 @@ function qFactory(nextTick, exceptionHandler, errorOnUnhandledRejections) {
function when ( value , callback , errback , progressBack ) {
var result = new Deferred ( ) ;
result . resolve ( value ) ;
return result . promise . then ( callback , errback , progressBack ) ;
var result = new Promise ( ) ;
resolvePromise ( result , value ) ;
return result . then ( callback , errback , progressBack ) ;
}
/**
@@ -594,25 +588,25 @@ function qFactory(nextTick, exceptionHandler, errorOnUnhandledRejections) {
*/
function all ( promises ) {
var deferred = new Deferred ( ) ,
var result = new Promise ( ) ,
counter = 0 ,
results = isArray ( promises ) ? [ ] : { } ;
forEach ( promises , function ( promise , key ) {
counter ++ ;
when ( promise ) . then ( function ( value ) {
results [ key ] = value ;
if ( !( -- counter ) ) deferred . resolve ( results ) ;
if ( !( -- counter ) ) resolvePromise ( result , results ) ;
} , function ( reason ) {
deferred . reject ( reason ) ;
rejectPromise ( result , reason ) ;
} ) ;
} ) ;
if ( counter === 0 ) {
deferred . resolve ( results ) ;
resolvePromise ( result , results ) ;
}
return deferred . promise ;
return result ;
}
/**
@@ -644,19 +638,19 @@ function qFactory(nextTick, exceptionHandler, errorOnUnhandledRejections) {
throw $qMinErr ( 'norslvr' , 'Expected resolverFn, got \'{0}\'' , resolver ) ;
}
var deferred = new Deferred ( ) ;
var promise = new Promise ( ) ;
function resolveFn ( value ) {
deferred . resolve ( value ) ;
resolvePromise ( promise , value ) ;
}
function rejectFn ( reason ) {
deferred . reject ( reason ) ;
rejectPromise ( promise , reason ) ;
}
resolver ( resolveFn , rejectFn ) ;
return deferred . promise ;
return promise ;
}
// Let's make the instanceof operator work for promises, so that