繁体   English   中英

是否可以改进此代码以避免内存泄漏或更稳定?

[英]Can this Code be Improved to Avoid Memory Leaks or be More Stable?

我编译了代码(发布在下面):

var keys = [];
var key1="17"; //ctrl
var key2="16"; //shift
var key3="83"; //s

window.addGlobalHotkey = function(callback,keyValues){
    if(typeof keyValues === "number")
        keyValues = [keyValues];

    var fnc = function(cb,val){
        return function(e){
            keys[e.keyCode] = true;
            executeHotkeyTest(cb,val);
        };        
    }(callback,keyValues);
    window.addEventListener('keydown',fnc);
    return fnc;
};

window.executeHotkeyTest = function(callback,keyValues){
    var allKeysValid = true;

    for(var i = 0; i < keyValues.length; ++i)
        allKeysValid = allKeysValid && keys[keyValues[i]];

    if(allKeysValid)
        callback();
};

window.addEventListener('keyup',function(e){
    keys[e.keyCode] = false;
});

addGlobalHotkey(function(){
    var x = getIn("What Task?");
        switch(x)
        {
            case "a":
                //...
            break;
            case "t":
                //...
                break;
            default:
                //...;
        }
},[key1,key2,key3]);

function getIn(text){

    var x = prompt(text);

    if (x != null && x != ''){
        return x;
    }              
}
  • 允许创建热键(在我的例子中为Ctrl + Shift + S
  • 旨在调出一个输入框(又名prompt
  • 并采取命令(一些预定义的switch或选项)
  • addGlobalHotkey(function(){/PLAY HERE/},[key1,key2,key3]);

所以现在你有了整个背景。 它使用GreaseMonkey和TamperMonkey在Firefox,Chrome中运行良好,并且完全符合我的需要。

但是,我注意到在任何给定的选项卡上执行它后,该特定选项卡开始逐渐变慢,挂起,延迟涂料,只有解决方案是关闭它。 其他选项卡不受影响,只是您执行时所在的选项卡。 所以我担心可能会有内存泄漏,这是我错过的代码中的东西吗? 可以以某种方式改进,以确保不是这样吗?

另外,我注意到99%以上的时间,它释放键很好,有时你按下键盘上的任意键并执行命令,这表明钩子没有正确清理后本身,导致任何键被困,并处理触发器,即使不是指定的键,我想念的是什么? 稳定性能提高吗?

你可以做几件事但我没有看到内存泄漏的原因。

我评论了我的编辑。

var keys = [];

// Integers takes less space than strings, and we might as well put it in an array already
var shortcut = [
    17, // ctrl
    16, // shift
    83  // s
];

window.addGlobalHotkey = function(callback, keyValues){
    if(typeof keyValues === "number")
        keyValues = [keyValues];

    // Unfortunately, because you need the cb argument we can't define it outside the addGlobalHotkey method.
    var fnc = function(cb, val){
        return function(e){
            keys[e.keyCode] = true;
            executeHotkeyTest(cb, val);
        };        
    }(callback, keyValues);

    window.addEventListener('keydown', fnc);
    return fnc;
};

window.executeHotkeyTest = function(callback, keyValues) {
    var i = keyValues.length;

    while(i--) {
        // If key is not pressed, we might as well abort
        if(!keys[keyValues[i]]) return;
    }

    callback();
};

window.addEventListener('keyup',function(e) {
    // Remove key instead of setting it to false
    keys.splice(e.keyCode, 1);
});

addGlobalHotkey(function() {
    var x = getIn("What Task?");

    // If x is empty there's no point in resuming
    if(!x) return;

    // If-statements are faster than switches, just saying.
    switch(x)
    {
        case "a":
            //...
        break;
        case "t":
            //...
            break;
        default:
            //...;
    }
}, shortcut);

function getIn(text){
    var x = prompt(text);

    // Altered if statement
    if(typeof x === 'string' && x.length > 0) return x;
}

最可能的泄漏事实是,只要按下更多不同的键,阵列键就会增长。 因此.splice()方法。


编辑

我再次审核了您的代码。 每当你注册一个新的热键时,我都会注意到你创建了一个新的onkeydown监听器。 我已经改变了。 请尝试使用以下代码,看看它是否仍然运行缓慢。

/* VARIABLES */

var keysPressed = [];
var hotkeys = [];

/* EVENT LISTENERS */

// Listen for keydown once instead for every hotkey
window.addEventListener('keydown', function(e) {
    // A button was pressed
    keysPressed[e.keyCode] = true;
    checkHotkeys();
}, false);

window.addEventListener('keyup', function(e) {
    // Remove key
    keysPressed.splice(e.keyCode, 1);
}, false);

/* FUNCTIONS */

function checkHotkeys() {
    var i = hotkeys.length;

    while(i--) {
        executeHotkeyTest(
            hotkeys[i].callback,
            hotkeys[i].keys
        );
    }
};

function addGlobalHotkey(callback, keys) {
    if(typeof keys === "number")
        keys = [keys];

    hotkeys.push({
        callback: callback,
        keys: keys
    });
};

function executeHotkeyTest(callback, keys) {
    var i = keys.length;

    while(i--) {
        // If key is not pressed, we might as well abort
        if(!keysPressed[keys[i]]) return;
    }

    callback();
};

function getIn(text){
    var x = prompt(text);

    // Altered if statement
    if(typeof x === 'string' && x.length > 0) return x;
}

/* OTHER */

// Integers takes less space than strings
var shortcut = [
    17, // ctrl
    16, // shift
    83  // s
];

addGlobalHotkey(function() {
    var x = getIn("What Task?");

    // If-statements are faster than switches, just saying.
    switch(x)
    {
        case "a":
            //...
        break;
        case "t":
            //...
            break;
        default:
            //...;
    }
}, shortcut);

编辑#2

我发现了这个问题!

所以我们一直使用keycode作为数组的索引 - 一个数字索引。 这些不是关联的。 看看下面的例子。

0: 'abc',
1: 'def',
2: 'ghi'

删除1

0: 'abc',
1: 'ghi'

删除2

0: 'abc',
1: 'ghi'

通过将它们转换为字符串,您的数组将成为关联数组,并且将删除正确的键。

// Listen for keydown once instead for every hotkey
window.addEventListener('keydown', function(e) {
    // A button was pressed
    keysPressed[e.keyCode.toString()] = true;
    checkHotkeys();
}, false);

window.addEventListener('keyup', function(e) {
    // Remove key
    delete keysPressed[e.keyCode.toString()];
}, false);

查看工作演示: http//jsfiddle.net/rQePB/1/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM