Javascript函数数组或函数包装/嵌套更适合手动/直接“事件”订阅吗?

时间:2013-09-05 03:51:53

标签: javascript performance events memory javascript-events

我经常需要让我自己的库通过回调订阅发出事件,在某些情况下,我更喜欢直接使用Javascript函数变量而不是某些第三方库或DOM来管理事件。我找到了两种策略,我不确定哪种策略更合适。

这些策略通过这个JSFiddle演示:http://jsfiddle.net/Q8pQT/2/

第一个策略是将每个订阅添加到一个函数数组,所以当我准备调用一个事件时,我可以迭代事件中的所有回调。

var fnactionidx = 0;
var fnarr = [];
function add2fnArray() {
    fnarr.push(fnaction);
    console.log("added to array", fnarr.length);
}
function fnaction() {
    console.log("Hi.", ++fnactionidx);
}
function arraygo() {

    // do internal stuff here first

    fnactionidx = 0;
    for (var i=0; i<fnarr.length; i++) {
        fnarr[i]();
    }
    console.log("array complete!")

    // do internal stuff here last
}

此示例中的订阅是使用简单的Array.push(fn)完成的。

第二个策略是定义一个初始函数,然后为每个订阅者用一个包含函数包装它。

function fnactionnested() {
   console.log("nested complete!");

    // do internal stuff here last
}

function nestfn(fn) {
    var na = fnactionnested;
    fnactionnested = function() {
        fn();
        na();        
    }
    console.log("nested " + fn.toString());
}
function nestgo() {
    // do internal stuff here first
    fnactionidx = 0;
    fnactionnested();
}

此示例中的订阅是使用nestfn完成的。请注意,我并不关心执行发生的顺序顺序,因为它是明确的;在第一个例子中,我可以使用Array.unshift。

我见过第二个推荐的更多。我的怀疑是,虽然第二个更像Javascript,因为它利用了Javascript灵活的函数作为函数式语言,它可能会引入更多的内存开销,因为你在包装器函数内部的包装器函数中有函数,等等,取决于有多少订户。

有关哪种方法更可取的想法?

请注意,我不想使用基于字符串的事件子系统,我只想区分这两种策略,或者是否有另一种回调策略可以执行与这两种策略非常相似的操作,而无需通过某些“全局”带有一些字符串键的事件系统。

1 个答案:

答案 0 :(得分:0)

根据Knockout subscribable subscribe implementation(第35行)判断,似乎使用数组进行事件订阅已被相当受欢迎的先例使用。

还有一个重要的论据是基于数组来支持取消订阅这样的事件。使用数组可以做到这一点;功能包装几乎不可能。

另外,功能包装,当你用头包住它时,只是很奇怪,它可能更容易编写,但它不容易支持。另一方面,有些时候你别无选择,例如当另一个模块已经实现了一个事件,你的目标是在应用程序代码中的其他回调执行之前执行一些预处理。

相关问题