下划线库提供了一个反跳功能,该功能可防止在设定的时间内多次调用该功能。他们的版本使用setTimeout。
我们如何用纯AngularJS代码做到这一点?
此外,我们可以利用$ q样式的承诺在反跳周期之后从调用的函数中检索返回值吗?
这是此类服务的工作示例:http : //plnkr.co/edit/fJwRER?p=preview。它创建了一个$q延迟对象,该对象将在最终调用去抖动功能时解决。
$q
每次debounce调用该函数时,都会返回对内部函数的下一次调用的承诺。
debounce
// Create an AngularJS service called debounce app.factory('debounce', ['$timeout','$q', function($timeout, $q) { // The service is actually this function, which we call with the func // that should be debounced and how long to wait in between calls return function debounce(func, wait, immediate) { var timeout; // Create a deferred object that will be resolved when we need to // actually call the func var deferred = $q.defer(); return function() { var context = this, args = arguments; var later = function() { timeout = null; if(!immediate) { deferred.resolve(func.apply(context, args)); deferred = $q.defer(); } }; var callNow = immediate && !timeout; if ( timeout ) { $timeout.cancel(timeout); } timeout = $timeout(later, wait); if (callNow) { deferred.resolve(func.apply(context,args)); deferred = $q.defer(); } return deferred.promise; }; }; }]);
通过在promise上使用then方法,可以从去抖动的函数中获取返回值。
$scope.addMsg = function(msg) { console.log('addMsg called with', msg); return msg; }; $scope.addMsgDebounced = debounce($scope.addMsg, 2000, false); $scope.logReturn = function(msg) { console.log('logReturn called with', msg); var promise = $scope.addMsgDebounced(msg); promise.then(function(msg) { console.log('Promise resolved with', msg); }); };
如果您logReturn连续快速拨打了多次电话,您将看到logReturn一遍又一遍的通话记录,但只有一个addMsg通话记录。
logReturn
addMsg