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

Commit 9524d49

Browse files
committed
perf($rootScope): make postDigestQueue more efficient
1 parent 707664a commit 9524d49

File tree

2 files changed

+48
-2
lines changed

2 files changed

+48
-2
lines changed

src/ng/rootScope.js

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -848,7 +848,7 @@ function $RootScopeProvider() {
848848

849849
clearPhase();
850850

851-
while (postDigestQueue.length) {
851+
while (!postDigestQueue.isEmpty()) {
852852
try {
853853
postDigestQueue.shift()();
854854
} catch (e) {
@@ -1306,7 +1306,7 @@ function $RootScopeProvider() {
13061306

13071307
//The internal queues. Expose them on the $rootScope for debugging/testing purposes.
13081308
var asyncQueue = $rootScope.$$asyncQueue = [];
1309-
var postDigestQueue = $rootScope.$$postDigestQueue = [];
1309+
var postDigestQueue = $rootScope.$$postDigestQueue = new Queue();
13101310
var applyAsyncQueue = $rootScope.$$applyAsyncQueue = [];
13111311

13121312
return $rootScope;
@@ -1364,5 +1364,28 @@ function $RootScopeProvider() {
13641364
});
13651365
}
13661366
}
1367+
1368+
// A simple queue implementation used for postDigestQueue,
1369+
// taken from http://code.stephenmorley.org/javascript/queues/
1370+
// See https://github.com/angular/angular.js/issues/14534
1371+
function Queue() {
1372+
var queue = [];
1373+
var offset = 0;
1374+
this.isEmpty = function() {
1375+
return queue.length === 0;
1376+
};
1377+
this.push = function(item) {
1378+
queue.push(item);
1379+
};
1380+
this.shift = function() {
1381+
if (queue.length === 0) return undefined;
1382+
var item = queue[offset];
1383+
if (++offset * 2 >= queue.length) {
1384+
queue = queue.slice(offset);
1385+
offset = 0;
1386+
}
1387+
return item;
1388+
};
1389+
}
13671390
}];
13681391
}

test/ng/rootScopeSpec.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1320,6 +1320,29 @@ describe('Scope', function() {
13201320
expect(externalWatchCount).toEqual(0);
13211321
}));
13221322

1323+
it('should process $$postDigest callbacks as a queue (FIFO) when the scope is digested', inject(function($rootScope) {
1324+
var result = '';
1325+
1326+
$rootScope.$$postDigest(function() {
1327+
result += 'a';
1328+
$rootScope.$$postDigest(function() {
1329+
result += 'd';
1330+
});
1331+
});
1332+
1333+
$rootScope.$$postDigest(function() {
1334+
result += 'b';
1335+
});
1336+
1337+
$rootScope.$$postDigest(function() {
1338+
result += 'c';
1339+
});
1340+
1341+
expect(result).toBe('');
1342+
$rootScope.$digest();
1343+
expect(result).toBe('abcd');
1344+
}));
1345+
13231346
it('should run a $$postDigest call on all child scopes when a parent scope is digested', inject(function($rootScope) {
13241347
var parent = $rootScope.$new(),
13251348
child = parent.$new(),

0 commit comments

Comments
 (0)