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

时间:2013-12-18 02:18:58

标签: javascript requirejs underscore.js

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

有没有人创造出比这更好的选择?以下是问题的解答: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();  

});

2 个答案:

答案 0 :(得分:1)

你有错误的网址要强调。要链接到github javascript文件,您应该使用具有正确标头的rawgithub.com....。请注意,这仍然是一种不良做法see this thread。使用:https://rawgithub.com/jashkenas/underscore/master/underscore.js

答案 1 :(得分:1)

debounce的{​​{3}}表示去抖动的功能是从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();
}

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

(ETA:我从megawac的评论中看到,该项目的github主分支中的下划线版本有AMD支持。但是,这个版本似乎还没有发布。我不喜欢使用开发版本除非有一些非常令人信服的理由这样做。我对下划线需要垫片的评论适用于此日期发布的下划线版本。可能,下一版本不需要垫片。)