refactor($interval): share code between $interval and ngMock/$interval
This avoids code/logic duplication and helps the implementations stay in-sync.
This commit is contained in:
Vendored
+1
@@ -28,6 +28,7 @@ var angularFiles = {
|
||||
'src/ng/httpBackend.js',
|
||||
'src/ng/interpolate.js',
|
||||
'src/ng/interval.js',
|
||||
'src/ng/intervalFactory.js',
|
||||
'src/ng/jsonpCallbacks.js',
|
||||
'src/ng/locale.js',
|
||||
'src/ng/location.js',
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
$FilterProvider,
|
||||
$$ForceReflowProvider,
|
||||
$InterpolateProvider,
|
||||
$$IntervalFactoryProvider,
|
||||
$IntervalProvider,
|
||||
$HttpProvider,
|
||||
$HttpParamSerializerProvider,
|
||||
@@ -241,6 +242,7 @@ function publishExternalAPI(angular) {
|
||||
$$forceReflow: $$ForceReflowProvider,
|
||||
$interpolate: $InterpolateProvider,
|
||||
$interval: $IntervalProvider,
|
||||
$$intervalFactory: $$IntervalFactoryProvider,
|
||||
$http: $HttpProvider,
|
||||
$httpParamSerializer: $HttpParamSerializerProvider,
|
||||
$httpParamSerializerJQLike: $HttpParamSerializerJQLikeProvider,
|
||||
|
||||
+13
-48
@@ -4,10 +4,18 @@ var $intervalMinErr = minErr('$interval');
|
||||
|
||||
/** @this */
|
||||
function $IntervalProvider() {
|
||||
this.$get = ['$rootScope', '$window', '$q', '$$q', '$browser',
|
||||
function($rootScope, $window, $q, $$q, $browser) {
|
||||
this.$get = ['$$intervalFactory', '$window',
|
||||
function($$intervalFactory, $window) {
|
||||
var intervals = {};
|
||||
|
||||
var setIntervalFn = function(tick, delay, deferred) {
|
||||
var id = $window.setInterval(tick, delay);
|
||||
intervals[id] = deferred;
|
||||
return id;
|
||||
};
|
||||
var clearIntervalFn = function(id) {
|
||||
$window.clearInterval(id);
|
||||
delete intervals[id];
|
||||
};
|
||||
|
||||
/**
|
||||
* @ngdoc service
|
||||
@@ -135,49 +143,7 @@ function $IntervalProvider() {
|
||||
* </file>
|
||||
* </example>
|
||||
*/
|
||||
function interval(fn, delay, count, invokeApply) {
|
||||
var hasParams = arguments.length > 4,
|
||||
args = hasParams ? sliceArgs(arguments, 4) : [],
|
||||
setInterval = $window.setInterval,
|
||||
clearInterval = $window.clearInterval,
|
||||
iteration = 0,
|
||||
skipApply = (isDefined(invokeApply) && !invokeApply),
|
||||
deferred = (skipApply ? $$q : $q).defer(),
|
||||
promise = deferred.promise;
|
||||
|
||||
count = isDefined(count) ? count : 0;
|
||||
|
||||
promise.$$intervalId = setInterval(function tick() {
|
||||
if (skipApply) {
|
||||
$browser.defer(callback);
|
||||
} else {
|
||||
$rootScope.$evalAsync(callback);
|
||||
}
|
||||
deferred.notify(iteration++);
|
||||
|
||||
if (count > 0 && iteration >= count) {
|
||||
deferred.resolve(iteration);
|
||||
clearInterval(promise.$$intervalId);
|
||||
delete intervals[promise.$$intervalId];
|
||||
}
|
||||
|
||||
if (!skipApply) $rootScope.$apply();
|
||||
|
||||
}, delay);
|
||||
|
||||
intervals[promise.$$intervalId] = deferred;
|
||||
|
||||
return promise;
|
||||
|
||||
function callback() {
|
||||
if (!hasParams) {
|
||||
fn(iteration);
|
||||
} else {
|
||||
fn.apply(null, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var interval = $$intervalFactory(setIntervalFn, clearIntervalFn);
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
@@ -205,8 +171,7 @@ function $IntervalProvider() {
|
||||
// Interval cancels should not report an unhandled promise.
|
||||
markQExceptionHandled(deferred.promise);
|
||||
deferred.reject('canceled');
|
||||
$window.clearInterval(id);
|
||||
delete intervals[id];
|
||||
clearIntervalFn(id);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
'use strict';
|
||||
|
||||
/** @this */
|
||||
function $$IntervalFactoryProvider() {
|
||||
this.$get = ['$browser', '$q', '$$q', '$rootScope',
|
||||
function($browser, $q, $$q, $rootScope) {
|
||||
return function intervalFactory(setIntervalFn, clearIntervalFn) {
|
||||
return function intervalFn(fn, delay, count, invokeApply) {
|
||||
var hasParams = arguments.length > 4,
|
||||
args = hasParams ? sliceArgs(arguments, 4) : [],
|
||||
iteration = 0,
|
||||
skipApply = isDefined(invokeApply) && !invokeApply,
|
||||
deferred = (skipApply ? $$q : $q).defer(),
|
||||
promise = deferred.promise;
|
||||
|
||||
count = isDefined(count) ? count : 0;
|
||||
|
||||
function callback() {
|
||||
if (!hasParams) {
|
||||
fn(iteration);
|
||||
} else {
|
||||
fn.apply(null, args);
|
||||
}
|
||||
}
|
||||
|
||||
function tick() {
|
||||
if (skipApply) {
|
||||
$browser.defer(callback);
|
||||
} else {
|
||||
$rootScope.$evalAsync(callback);
|
||||
}
|
||||
deferred.notify(iteration++);
|
||||
|
||||
if (count > 0 && iteration >= count) {
|
||||
deferred.resolve(iteration);
|
||||
clearIntervalFn(promise.$$intervalId);
|
||||
}
|
||||
|
||||
if (!skipApply) $rootScope.$apply();
|
||||
}
|
||||
|
||||
promise.$$intervalId = setIntervalFn(tick, delay, deferred, skipApply);
|
||||
|
||||
return promise;
|
||||
};
|
||||
};
|
||||
}];
|
||||
}
|
||||
Vendored
+34
-68
@@ -537,72 +537,40 @@ angular.mock.$LogProvider = function() {
|
||||
* @returns {promise} A promise which will be notified on each iteration.
|
||||
*/
|
||||
angular.mock.$IntervalProvider = function() {
|
||||
this.$get = ['$browser', '$rootScope', '$q', '$$q',
|
||||
function($browser, $rootScope, $q, $$q) {
|
||||
this.$get = ['$browser', '$$intervalFactory',
|
||||
function($browser, $$intervalFactory) {
|
||||
var repeatFns = [],
|
||||
nextRepeatId = 0,
|
||||
now = 0;
|
||||
now = 0,
|
||||
setIntervalFn = function(tick, delay, deferred, skipApply) {
|
||||
var id = nextRepeatId++;
|
||||
var fn = !skipApply ? tick : function() {
|
||||
tick();
|
||||
$browser.defer.flush();
|
||||
};
|
||||
|
||||
var $interval = function(fn, delay, count, invokeApply) {
|
||||
var hasParams = arguments.length > 4,
|
||||
args = hasParams ? Array.prototype.slice.call(arguments, 4) : [],
|
||||
iteration = 0,
|
||||
skipApply = (angular.isDefined(invokeApply) && !invokeApply),
|
||||
deferred = (skipApply ? $$q : $q).defer(),
|
||||
promise = deferred.promise;
|
||||
|
||||
count = (angular.isDefined(count)) ? count : 0;
|
||||
|
||||
promise.$$intervalId = nextRepeatId;
|
||||
|
||||
function tick() {
|
||||
if (skipApply) {
|
||||
$browser.defer(callback);
|
||||
} else {
|
||||
$rootScope.$evalAsync(callback);
|
||||
}
|
||||
deferred.notify(iteration++);
|
||||
|
||||
if (count > 0 && iteration >= count) {
|
||||
var fnIndex;
|
||||
deferred.resolve(iteration);
|
||||
|
||||
angular.forEach(repeatFns, function(fn, index) {
|
||||
if (fn.id === promise.$$intervalId) fnIndex = index;
|
||||
repeatFns.push({
|
||||
nextTime: (now + (delay || 0)),
|
||||
delay: delay || 1,
|
||||
fn: fn,
|
||||
id: id,
|
||||
deferred: deferred
|
||||
});
|
||||
repeatFns.sort(function(a, b) { return a.nextTime - b.nextTime; });
|
||||
|
||||
if (angular.isDefined(fnIndex)) {
|
||||
repeatFns.splice(fnIndex, 1);
|
||||
return id;
|
||||
},
|
||||
clearIntervalFn = function(id) {
|
||||
for (var fnIndex = repeatFns.length - 1; fnIndex >= 0; fnIndex--) {
|
||||
if (repeatFns[fnIndex].id === id) {
|
||||
repeatFns.splice(fnIndex, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (skipApply) {
|
||||
$browser.defer.flush();
|
||||
} else {
|
||||
$rootScope.$apply();
|
||||
}
|
||||
}
|
||||
var $interval = $$intervalFactory(setIntervalFn, clearIntervalFn);
|
||||
|
||||
function callback() {
|
||||
if (!hasParams) {
|
||||
fn(iteration);
|
||||
} else {
|
||||
fn.apply(null, args);
|
||||
}
|
||||
}
|
||||
|
||||
repeatFns.push({
|
||||
nextTime: (now + (delay || 0)),
|
||||
delay: delay || 1,
|
||||
fn: tick,
|
||||
id: nextRepeatId,
|
||||
deferred: deferred
|
||||
});
|
||||
repeatFns.sort(function(a, b) { return a.nextTime - b.nextTime;});
|
||||
|
||||
nextRepeatId++;
|
||||
return promise;
|
||||
};
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name $interval#cancel
|
||||
@@ -615,17 +583,15 @@ angular.mock.$IntervalProvider = function() {
|
||||
*/
|
||||
$interval.cancel = function(promise) {
|
||||
if (!promise) return false;
|
||||
var fnIndex;
|
||||
|
||||
angular.forEach(repeatFns, function(fn, index) {
|
||||
if (fn.id === promise.$$intervalId) fnIndex = index;
|
||||
});
|
||||
|
||||
if (angular.isDefined(fnIndex)) {
|
||||
repeatFns[fnIndex].deferred.promise.then(undefined, function() {});
|
||||
repeatFns[fnIndex].deferred.reject('canceled');
|
||||
repeatFns.splice(fnIndex, 1);
|
||||
return true;
|
||||
for (var fnIndex = repeatFns.length - 1; fnIndex >= 0; fnIndex--) {
|
||||
if (repeatFns[fnIndex].id === promise.$$intervalId) {
|
||||
var deferred = repeatFns[fnIndex].deferred;
|
||||
deferred.promise.then(undefined, function() {});
|
||||
deferred.reject('canceled');
|
||||
repeatFns.splice(fnIndex, 1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user