一尘不染

如何在AngularJS中编写反跳服务

angularjs

下划线库提供了一个反跳功能,该功能可防止在设定的时间内多次调用该功能。他们的版本使用setTimeout。

我们如何用纯AngularJS代码做到这一点?

此外,我们可以利用$ q样式的承诺在反跳周期之后从调用的函数中检索返回值吗?


阅读 219

收藏
2020-07-04

共1个答案

一尘不染

这是此类服务的工作示例:http :
//plnkr.co/edit/fJwRER?p=preview。它创建了一个$q延迟对象,该对象将在最终调用去抖动功能时解决。

每次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通话记录。

2020-07-04