React 中基于调度循环的去抖动调用

Posted

技术标签:

【中文标题】React 中基于调度循环的去抖动调用【英文标题】:De-bounce calls based on dispatch loop in React 【发布时间】:2015-04-28 14:11:03 【问题描述】:

最近的 React.JS Conf 有 Flux 面板和 Kyle Davis mentioned 基于调度循环优化的去弹跳调用。谁能提供一些关于如何实现它的例子?

【问题讨论】:

【参考方案1】:

我的理解是它看起来像这样:

function debounce(duration) 
    var _timer = null;
    var toCall = [];

    function dispatch() 
        _timer = null;
        toCall.forEach(function(opts) 
            if (opts.shouldCall) 
                opts.fn.apply(undefined, opts.args);
            
            opts.shouldCall = false;
        );
    

    return function debounce(fn) 
        var myAction = fn: fn, args: [], shouldCall: false;
        toCall.push(myAction);

        return function() 
            myAction.shouldCall = true;
            myAction.args = Array.prototype.slice.call(arguments);

            clearTimeout(_timer);
            _timer = setTimeout(dispatch, duration);
        ;
    ;

这看起来很复杂,但实际上只是尾随共享去抖动。多个函数在同一个计时器上去抖动,并且所有函数都在同一个滴答声中调用。保留最新的参数(在这种特定情况下不需要,但不会导致问题)。

我们为所有(不是每个)商店创建其中一个。持续时间大多是任意的,但足以让浏览器在我们执行商店更新逻辑和 UI 更新之间呈现一个框架,这可能会使滚动感觉更灵敏。

var storeDebounce = debouncer(20);

在我们的商店,而不是这个:

  emitChange: function() 
    this.emit(CHANGE_EVENT);
  ,

我们这样做:

  emitChange: storeDebounce(function() 
    this.emit(CHANGE_EVENT);
  .bind(this)),

现在,如果一个或多个 store 在同一个 tick 或短暂的连续更新中多次更新(通常发生在 Promise 或其他有保证的异步代码中),我们只会为每个受影响的 store 发出一个 change 事件。

免责声明:未经测试

【讨论】:

你能稍微介绍一下We create one of these for all (not each) of our stores吗? @message,否则每个 store 的 change 事件会有不同的 setTimeout,并且它们都会一个接一个地发送出去,可能导致某些组件具有过时的数据甚至错误应该是不可能的。优化中的第 1 点重要的事情是您不会按照最佳实践破坏任何东西(第 2 点不会破坏任何东西,但有时这是允许的)。 所以,所有商店都需要一个emitChange: storeDebounce?!应该在哪里定义它以影响所有商店?您能否添加一些使用 2 个商店和共享的 emitchange 的示例(如果它按我想的方式工作)? @message,它只是一个函数,所以你可以弄清楚你想如何将它提供给商店(把它放在一个模块中,在初始化它们时从 main.js 传递它,使用 DI框架等) loadashunderscore debouncer 是否与您的实现不同?

以上是关于React 中基于调度循环的去抖动调用的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI 中来自 BindableObject 的去抖动方法调用

Lodash 使用 React 输入去抖动

通过参数去抖动函数调用

在 React Redux 中调度操作之前等待多个 Axios 调用

React Hook - 无法在子组件 onComplete 回调中调用父组件调度

React 和 Flux:“在调度中间调度”以显示来自 API 调用的错误消息