如何在 AngularJS 中编写去抖动服务 [英] How to write a debounce service in AngularJS

查看:23
本文介绍了如何在 AngularJS 中编写去抖动服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

underscore 库提供了一个 debounce 函数,可以防止在设定的时间段内多次调用一个函数.他们的版本使用了 setTimeout.

The underscore library provides a debounce function that prevents multiple calls to a function within a set period of time. Their version makes use of setTimeout.

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

How could we do this in pure AngularJS code?

此外,我们是否可以利用 $q 样式的 promise 来在 debounce 周期后从被调用函数中检索返回值?

Moreover, can we make use of $q style promises to retrieve the return value from the called function after the debounce period?

推荐答案

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

Here is a working example of such a service: http://plnkr.co/edit/fJwRER?p=preview. It creates a $q deferred object that will be resolved when the debounced function is finally called.

每次调用 debounce 函数时,都会返回对内部函数下一次调用的承诺.

Each time the debounce function is called the promise to the next call of the inner function is returned.

// 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 方法从去抖动函数中获取返回值.

You get the return value from the debounced function by using the then method on the promise.

$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 调用.

If you call logReturn multiple times in quick succession you will see the logReturn call logged over and over but only one addMsg call logged.

这篇关于如何在 AngularJS 中编写去抖动服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆