This repository was archived by the owner on Apr 12, 2024. It is now read-only.
File tree 3 files changed +48
-3
lines changed
3 files changed +48
-3
lines changed Original file line number Diff line number Diff line change
1
+ @ngdoc error
2
+ @name $q:qcycle
3
+ @fullName Cannot resolve a promise with itself
4
+ @description
5
+
6
+ Occurs when resolving a promise with itself as the value, including returning the promise in a
7
+ function passed to `then`. The A+ 1.1 spec mandates that this behavior throw a TypeError.
8
+ https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure
9
+
10
+ ```
11
+ var promise = $q.defer().promise;
12
+
13
+ //bad
14
+ promise.then(function (val) {
15
+ //Cannot return self
16
+ return promise;
17
+ });
18
+
19
+ //good
20
+ promise.then(function (val) {
21
+ return 'some other value';
22
+ });
23
+ ```
Original file line number Diff line number Diff line change @@ -235,7 +235,7 @@ function $$QProvider() {
235
235
* @returns {object } Promise manager.
236
236
*/
237
237
function qFactory ( nextTick , exceptionHandler ) {
238
- var $qMinErr = minErr ( '$q' ) ;
238
+ var $qMinErr = minErr ( '$q' , TypeError ) ;
239
239
function callOnce ( self , resolveFn , rejectFn ) {
240
240
var called = false ;
241
241
function wrap ( fn ) {
@@ -338,8 +338,16 @@ function qFactory(nextTick, exceptionHandler) {
338
338
Deferred . prototype = {
339
339
resolve : function ( val ) {
340
340
if ( this . promise . $$state . status ) return ;
341
- if ( val === this . promise ) throw new TypeError ( 'Cycle detected' ) ;
342
- this . $$resolve ( val ) ;
341
+ if ( val === this . promise ) {
342
+ this . $$reject ( $qMinErr (
343
+ 'qcycle' ,
344
+ "Expected promise to be resolved with value other than itself '{0}'" ,
345
+ val ) ) ;
346
+ }
347
+ else {
348
+ this . $$resolve ( val ) ;
349
+ }
350
+
343
351
} ,
344
352
345
353
$$resolve : function ( val ) {
Original file line number Diff line number Diff line change @@ -815,6 +815,20 @@ describe('q', function() {
815
815
} ) ;
816
816
817
817
818
+ it ( 'should complain if promise fulfilled with itself' , function ( ) {
819
+ var resolveSpy = jasmine . createSpy ( 'resolve' ) ;
820
+ var rejectSpy = jasmine . createSpy ( 'reject' ) ;
821
+ promise . then ( resolveSpy , rejectSpy ) ;
822
+ deferred . resolve ( deferred . promise ) ;
823
+ mockNextTick . flush ( ) ;
824
+
825
+ expect ( resolveSpy ) . not . toHaveBeenCalled ( ) ;
826
+ expect ( rejectSpy ) . toHaveBeenCalled ( ) ;
827
+ expect ( rejectSpy . calls [ 0 ] . args [ 0 ] . message ) .
828
+ toMatch ( / \[ \$ q \: q c y c l e \] E x p e c t e d p r o m i s e t o b e r e s o l v e d w i t h v a l u e o t h e r t h a n i t s e l f / ) ;
829
+ } ) ;
830
+
831
+
818
832
it ( 'should do nothing if a promise was previously resolved' , function ( ) {
819
833
promise . then ( success ( ) , error ( ) ) ;
820
834
expect ( logStr ( ) ) . toBe ( '' ) ;
You can’t perform that action at this time.
0 commit comments