Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit a25a8ce

Browse files
committed
refactor($q): separate Promise from Deferred
1 parent 53a3bf6 commit a25a8ce

File tree

1 file changed

+98
-105
lines changed

1 file changed

+98
-105
lines changed

src/ng/q.js

+98-105
Original file line numberDiff line numberDiff line change
@@ -299,14 +299,18 @@ function qFactory(nextTick, exceptionHandler, errorOnUnhandledRejections) {
299299
* @returns {Deferred} Returns a new instance of deferred.
300300
*/
301301
var defer = function() {
302-
var d = new Deferred();
303-
//Necessary to support unbound execution :/
304-
d.resolve = simpleBind(d, d.resolve);
305-
d.reject = simpleBind(d, d.reject);
306-
d.notify = simpleBind(d, d.notify);
307-
return d;
302+
return new Deferred();
308303
};
309304

305+
function Deferred() {
306+
var promise = this.promise = new Promise();
307+
//Non prototype methods necessary to support unbound execution :/
308+
this.resolve = function(val) { resolvePromise(promise, val); };
309+
this.reject = function(reason) { rejectPromise(promise, reason); };
310+
this.notify = function(progress) { notifyPromise(promise, progress); };
311+
}
312+
313+
310314
function Promise() {
311315
this.$$state = { status: 0 };
312316
}
@@ -316,13 +320,13 @@ function qFactory(nextTick, exceptionHandler, errorOnUnhandledRejections) {
316320
if (isUndefined(onFulfilled) && isUndefined(onRejected) && isUndefined(progressBack)) {
317321
return this;
318322
}
319-
var result = new Deferred();
323+
var result = new Promise();
320324

321325
this.$$state.pending = this.$$state.pending || [];
322326
this.$$state.pending.push([result, onFulfilled, onRejected, progressBack]);
323327
if (this.$$state.status > 0) scheduleProcessQueue(this.$$state);
324328

325-
return result.promise;
329+
return result;
326330
},
327331

328332
'catch': function(callback) {
@@ -338,34 +342,27 @@ function qFactory(nextTick, exceptionHandler, errorOnUnhandledRejections) {
338342
}
339343
});
340344

341-
//Faster, more basic than angular.bind http://jsperf.com/angular-bind-vs-custom-vs-native
342-
function simpleBind(context, fn) {
343-
return function(value) {
344-
fn.call(context, value);
345-
};
346-
}
347-
348345
function processQueue(state) {
349-
var fn, deferred, pending;
346+
var fn, promise, pending;
350347

351348
pending = state.pending;
352349
state.processScheduled = false;
353350
state.pending = undefined;
354351
try {
355352
for (var i = 0, ii = pending.length; i < ii; ++i) {
356353
state.pur = true;
357-
deferred = pending[i][0];
354+
promise = pending[i][0];
358355
fn = pending[i][state.status];
359356
try {
360357
if (isFunction(fn)) {
361-
deferred.resolve(fn(state.value));
358+
resolvePromise(promise, fn(state.value));
362359
} else if (state.status === 1) {
363-
deferred.resolve(state.value);
360+
resolvePromise(promise, state.value);
364361
} else {
365-
deferred.reject(state.value);
362+
rejectPromise(promise, state.value);
366363
}
367364
} catch (e) {
368-
deferred.reject(e);
365+
rejectPromise(promise, e);
369366
exceptionHandler(e);
370367
}
371368
}
@@ -410,85 +407,81 @@ function qFactory(nextTick, exceptionHandler, errorOnUnhandledRejections) {
410407
nextTick(processQueueFn(state));
411408
}
412409

413-
function Deferred() {
414-
this.promise = new Promise();
410+
function resolvePromise(promise, val) {
411+
if (promise.$$state.status) return;
412+
if (val === promise) {
413+
$$reject(promise, $qMinErr(
414+
'qcycle',
415+
'Expected promise to be resolved with value other than itself \'{0}\'',
416+
val));
417+
} else {
418+
$$resolve(promise, val);
419+
}
420+
415421
}
416422

417-
extend(Deferred.prototype, {
418-
resolve: function(val) {
419-
if (this.promise.$$state.status) return;
420-
if (val === this.promise) {
421-
this.$$reject($qMinErr(
422-
'qcycle',
423-
'Expected promise to be resolved with value other than itself \'{0}\'',
424-
val));
423+
function $$resolve(promise, val) {
424+
var then;
425+
var done = false;
426+
try {
427+
if ((isObject(val) || isFunction(val))) then = val && val.then;
428+
if (isFunction(then)) {
429+
promise.$$state.status = -1;
430+
then.call(val, doResolve, doReject, doNotify);
425431
} else {
426-
this.$$resolve(val);
427-
}
428-
429-
},
430-
431-
$$resolve: function(val) {
432-
var then;
433-
var that = this;
434-
var done = false;
435-
try {
436-
if ((isObject(val) || isFunction(val))) then = val && val.then;
437-
if (isFunction(then)) {
438-
this.promise.$$state.status = -1;
439-
then.call(val, resolvePromise, rejectPromise, simpleBind(this, this.notify));
440-
} else {
441-
this.promise.$$state.value = val;
442-
this.promise.$$state.status = 1;
443-
scheduleProcessQueue(this.promise.$$state);
444-
}
445-
} catch (e) {
446-
rejectPromise(e);
447-
exceptionHandler(e);
432+
promise.$$state.value = val;
433+
promise.$$state.status = 1;
434+
scheduleProcessQueue(promise.$$state);
448435
}
436+
} catch (e) {
437+
doReject(e);
438+
exceptionHandler(e);
439+
}
449440

450-
function resolvePromise(val) {
451-
if (done) return;
452-
done = true;
453-
that.$$resolve(val);
454-
}
455-
function rejectPromise(val) {
456-
if (done) return;
457-
done = true;
458-
that.$$reject(val);
459-
}
460-
},
441+
function doResolve(val) {
442+
if (done) return;
443+
done = true;
444+
$$resolve(promise, val);
445+
}
446+
function doReject(val) {
447+
if (done) return;
448+
done = true;
449+
$$reject(promise, val);
450+
}
451+
function doNotify(progress) {
452+
notifyPromise(promise, progress);
453+
}
454+
}
461455

462-
reject: function(reason) {
463-
if (this.promise.$$state.status) return;
464-
this.$$reject(reason);
465-
},
456+
function rejectPromise(promise, reason) {
457+
if (promise.$$state.status) return;
458+
$$reject(promise, reason);
459+
}
466460

467-
$$reject: function(reason) {
468-
this.promise.$$state.value = reason;
469-
this.promise.$$state.status = 2;
470-
scheduleProcessQueue(this.promise.$$state);
471-
},
461+
function $$reject(promise, reason) {
462+
promise.$$state.value = reason;
463+
promise.$$state.status = 2;
464+
scheduleProcessQueue(promise.$$state);
465+
}
472466

473-
notify: function(progress) {
474-
var callbacks = this.promise.$$state.pending;
475-
476-
if ((this.promise.$$state.status <= 0) && callbacks && callbacks.length) {
477-
nextTick(function() {
478-
var callback, result;
479-
for (var i = 0, ii = callbacks.length; i < ii; i++) {
480-
result = callbacks[i][0];
481-
callback = callbacks[i][3];
482-
try {
483-
result.notify(isFunction(callback) ? callback(progress) : progress);
484-
} catch (e) {
485-
exceptionHandler(e);
486-
}
467+
function notifyPromise(promise, progress) {
468+
var callbacks = promise.$$state.pending;
469+
470+
if ((promise.$$state.status <= 0) && callbacks && callbacks.length) {
471+
nextTick(function() {
472+
var callback, result;
473+
for (var i = 0, ii = callbacks.length; i < ii; i++) {
474+
result = callbacks[i][0];
475+
callback = callbacks[i][3];
476+
try {
477+
notifyPromise(result, isFunction(callback) ? callback(progress) : progress);
478+
} catch (e) {
479+
exceptionHandler(e);
487480
}
488-
});
489-
}
481+
}
482+
});
490483
}
491-
});
484+
}
492485

493486
/**
494487
* @ngdoc method
@@ -527,9 +520,9 @@ function qFactory(nextTick, exceptionHandler, errorOnUnhandledRejections) {
527520
* @returns {Promise} Returns a promise that was already resolved as rejected with the `reason`.
528521
*/
529522
var reject = function(reason) {
530-
var result = new Deferred();
531-
result.reject(reason);
532-
return result.promise;
523+
var result = new Promise();
524+
rejectPromise(result, reason);
525+
return result;
533526
};
534527

535528
var makePromise = function makePromise(value, resolved) {
@@ -579,9 +572,9 @@ function qFactory(nextTick, exceptionHandler, errorOnUnhandledRejections) {
579572

580573

581574
var when = function(value, callback, errback, progressBack) {
582-
var result = new Deferred();
583-
result.resolve(value);
584-
return result.promise.then(callback, errback, progressBack);
575+
var result = new Promise();
576+
resolvePromise(result, value);
577+
return result.then(callback, errback, progressBack);
585578
};
586579

587580
/**
@@ -617,7 +610,7 @@ function qFactory(nextTick, exceptionHandler, errorOnUnhandledRejections) {
617610
*/
618611

619612
function all(promises) {
620-
var deferred = new Deferred(),
613+
var result = new Promise(),
621614
counter = 0,
622615
results = isArray(promises) ? [] : {};
623616

@@ -626,18 +619,18 @@ function qFactory(nextTick, exceptionHandler, errorOnUnhandledRejections) {
626619
when(promise).then(function(value) {
627620
if (results.hasOwnProperty(key)) return;
628621
results[key] = value;
629-
if (!(--counter)) deferred.resolve(results);
622+
if (!(--counter)) resolvePromise(result, results);
630623
}, function(reason) {
631624
if (results.hasOwnProperty(key)) return;
632-
deferred.reject(reason);
625+
rejectPromise(result, reason);
633626
});
634627
});
635628

636629
if (counter === 0) {
637-
deferred.resolve(results);
630+
resolvePromise(result, results);
638631
}
639632

640-
return deferred.promise;
633+
return result;
641634
}
642635

643636
/**
@@ -669,19 +662,19 @@ function qFactory(nextTick, exceptionHandler, errorOnUnhandledRejections) {
669662
throw $qMinErr('norslvr', 'Expected resolverFn, got \'{0}\'', resolver);
670663
}
671664

672-
var deferred = new Deferred();
665+
var promise = new Promise();
673666

674667
function resolveFn(value) {
675-
deferred.resolve(value);
668+
resolvePromise(promise, value);
676669
}
677670

678671
function rejectFn(reason) {
679-
deferred.reject(reason);
672+
rejectPromise(promise, reason);
680673
}
681674

682675
resolver(resolveFn, rejectFn);
683676

684-
return deferred.promise;
677+
return promise;
685678
};
686679

687680
// Let's make the instanceof operator work for promises, so that

0 commit comments

Comments
 (0)