一个Javascript回调模式示例 - 它真的更有效吗?

A Javascript callback pattern example - is it really more efficient?

本文关键字:真的 有效 回调 Javascript 模式 一个      更新时间:2023-09-26

我读了一本在线书籍。它给出了一个回调模式示例,如下所示。

var findNodes = function () {
    var i = 100000, // big, heavy loop
        nodes = [], // stores the result
        found; // the next node found
    while (i) {
        i -= 1;
        // complex logic here...
        nodes.push(found);
    }
    return nodes;
};
var hide = function (nodes) {
    var i = 0, max = nodes.length;
    for (; i < max; i += 1) {
        nodes[i].style.display = "none";
    }
};
// executing the functions
hide(findNodes());

它说这效率不高,因为它循环遍历找到的节点两次,下面的代码更有效。

// refactored findNodes() to accept a callback
var findNodes = function (callback) {
    var i = 100000,
        nodes = [],
        found;
    // check if callback is callable
    if (typeof callback !== "function") {
        callback = false;
    }
    while (i) {
        i -= 1;
        // complex logic here...
        // now callback:
        if (callback) {
            callback(found);
        }
        nodes.push(found);
    }
    return nodes;
};
// a callback function
var hide = function (node) {
    node.style.display = "none";
};
// find the nodes and hide them as you go
findNodes(hide);

但是,它们都是 O(n),并且调用函数的开销可能很大,这会导致 findNodes()(带回调)中的每次迭代都需要更多时间。所以我想知道这种修改是否真的像作者所说的那样有所不同。我应该如何衡量这两种工具的成本?

根据数组的大小,只循环一次的示例可能更有效。

但是,您的担忧是正确的。特别是在稍旧的JS引擎中,函数调用中存在大量开销。

与所有性能优化一样,这是您应该衡量的内容。使用探查器测试代码以查找瓶颈,然后优化,然后重新运行分析以确定它是否具有积极影响。

我将这两个示例放在一个 HTML 文件中的两个函数中,并使用 Chrome 控制台对它们进行计时,如下所示:

console.time('slow'); slow(); console.timeEnd('slow');
console.time('fast'); fast(); console.timeEnd('fast');

这表明第一个示例("低效"示例)的运行速度是第二个实现的两倍。