簡體   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