可以从需要模块调用下划线去抖动吗?

Posted

技术标签:

【中文标题】可以从需要模块调用下划线去抖动吗?【英文标题】:Can underscore debounce be called from a requires module? 【发布时间】:2014-01-06 01:34:24 【问题描述】:

我无法在 requirejs 模块中使用下划线去抖动方法。作为替代方案,我可以通过 window.setTimeout 制作一个伪去抖动方法,但是我必须手动测试计时器。

有没有人创造出比这更好的选择?这是问题的一个jsfiddle:http://jsfiddle.net/ledlogic/gkY5C/

require.config(
paths: 
    'jquery': 'http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.min',
    'underscore': 'https://raw.github.com/documentcloud/underscore/master/underscore'

);

require(['jquery', 'underscore'], function ($, _) 
var flyStat = 
    pct: -1,
    delay: 0,
    timeout: null,

    rnd: function (i) 
        flyStat.pct = Math.random() * 100.0;
        flyStat.trns(i);
    ,
    // report transient state.  CALLED
    trns: function (i) 
        console.log("TRNS[" + i + "]: " + flyStat.pct);
    ,
    // report final state, called immediately at end. CALLED
    rpt: function () 
        console.log("RPT: " + flyStat.pct);
    ,
    // report final state, intended to be called from debounce. NOT CALLED
    rptd: function () 
        console.log("RPTD: " + flyStat.pct);
    ,
    // report final state, setup timeout calls.  CALLED
    rpto: function(delay) 
        if (flyStat.timeout) 
            window.clearTimeout(flyStat.timeout);
        
        flyStat.last = (new Date()).getTime();
        flyStat.delay = delay;
        flyStat.timeout = window.setTimeout(flyStat.rpto2, delay);
    ,
    // report final state, called from timeout call.  CALLED
    rpto2: function() 
        if (flyStat.last > flyStat.delay) 
            console.log("RPTO2: " + flyStat.pct);
        
    
;

// Can debounce call back into a requires define block?
// NO.
function dbc() 
    console.log("DBC: 1");

_.debounce(dbc, 10);

// Run a semi-lengthy running process (because of the console log activity, it lags a bit).
for (var i = 0; i < 1000; i++) 
    flyStat.rnd(i);

    // We want a debounced report, after 1 sec past the last one
    // Do we get it?
    // NO.
    _.debounce(flyStat.rptd, 1000);

    // Can we resort to classic timeout?
    // YES.
    flyStat.rpto(1000);

    // Is there a better way?
    // UNKNOWN.


// Immediate call at end (assumes we have sequential process with fixed known length and endpoint).
// Does this work?
// YES.
flyStat.rpt();  

);

【问题讨论】:

"可以去抖动回调到需要定义块吗?"这是什么意思? Underscore 不支持 amd 模块加载器 - 编辑 github 上的那个但是你使用了错误的链接:rawgithub.com/jashkenas/underscore/master/underscore.js 【参考方案1】:

debounce 的documentation 表明去抖函数是从debounce返回的函数:

创建并返回传递函数的新去抖动版本

(添加了重点。)以下是文档中的示例:

var lazyLayout = _.debounce(calculateLayout, 300);
$(window).resize(lazyLayout);

注意使用的回调 (lazyLayout) 是来自debounce 的返回值。问题中的代码没有使用debounce的返回值,所以不起作用。

RequireJS 与此无关。

这是一个如何使用它的示例,基于问题中的flyStat.rptflyStat.rptd

// Define flyStat but don't define rptd right away
var flyStat = 
[...]
;

// Create the debounced version of rpt.
flyStat.rptd = _.debounce(flyState.rpt, 1000);

for (var i = 0; i < 1000; i++) 
     flyStat.rnd(i);
     // Call the debounced version.
     flyStat.rptd();

这是一个从你那里分叉出来的工作 fiddle。请注意,下划线必须是 shimmed 才能与 RequireJS 一起正常工作。 (此问题独立与您使用 debounce 的方式有关。)您的两个 CDN 都不起作用。此外,1.8 之前的 jQuery 版本不能识别 AMD 类型的加载器(如 RequireJS)。因此,除非有令人信服的理由使用旧版本,否则请使用最新版本。如果您必须使用无法识别 RequireJS 的旧版本,则必须对其进行填充。

(ETA:我从megawac对项目的github主分支中下划线版本支持AMD的问题的评论中看到。但是,这个版本似乎还没有发布。我不想与开发版本一起工作除非有一些真正令人信服的理由这样做。我关于下划线需要垫片的评论适用于迄今为止发布的下划线版本。大概,下一个版本不需要垫片。)

【讨论】:

在此过程中,我停止调用 debounced 方法,感谢您的发现和您的见解。【参考方案2】:

下划线的网址有误。要链接到 github javascript 文件,您应该使用 rawgithub.com.... 它将具有正确的标题。请注意,这仍然是一个糟糕的做法see this thread。使用:https://rawgithub.com/jashkenas/underscore/master/underscore.js

【讨论】:

在我们的网站上,我们使用的是带垫片的下划线 1.4.4 + 要求,而 cdn 版本控制只是在 jsfiddle 中。谢谢建议,以后分享jsfiddles的时候会多加注意的。

以上是关于可以从需要模块调用下划线去抖动吗?的主要内容,如果未能解决你的问题,请参考以下文章

将 debouncer 与 React 事件一起使用

我应该用下划线开始一个辅助函数吗? [复制]

Lodash 使用 React 输入去抖动

matlab中的m文件可以用中文命名吗,或者用数字?

我可以在 XForms 标签和提示上添加丰富的格式(粗体、斜体、下划线)吗?

Python双下划线方法解释