5
votes

L'intervalle SettimeOut échoue avec "Impossible de convertir undefined ou null en objet"

Je me lance dans le script utilisateur avec tampermonkey et je ne parviens pas à résoudre cette erreur, toute aide serait appréciée.

Je détecte bien les clés, la touche espace déclenche cette fonction qui se répète tant que la clé reste en position basse. La console écrit la sortie normalement pendant 30 secondes plus ou moins, puis il y a une TypeError.

Comme pour la restriction de réputation, voici une capture d'écran:

User-Script:

// ==UserScript==
// @name         TEST STUFF--------------------
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @run-at         document-start
// @include        http://*
// @include        https://*
// @grant        none
// ==/UserScript==

( function()
{
    'use strict';
    window.addEventListener ( "keydown", CaptureKeyPress );
    window.addEventListener ( "keyup", CaptureKeyPress );
    var Hotkeys =
    {
        perform: 32
    };
    var HotkeyToggle = false;
    function CaptureKeyPress ( a )
    {
        if ( a.keyCode == Hotkeys.perform )
        {
            a.preventDefault();
            a.stopPropagation();
            a.cancelBubble = true;
            a.stopImmediatePropagation();

            if ( a.type == "keydown" && !HotkeyToggle )
            {
                console.clear();
                HotkeyToggle = true;
                perform();
            }

            if ( a.type == "keyup" && HotkeyToggle )
            {
                HotkeyToggle = false;
            }
        }
    }
    function perform()
    {
        if(HotkeyToggle == false) // exit
        {
            return 0
        }
        //do stuff...

        console.info("working...");
        if(HotkeyToggle == true) // continue after everything completes
        {
            setTimeout(() => {
                perform()
            }, 280);
            return 0
        }
        return 1
    }
} ) ();


6 commentaires

Sur quelle ligne du code que vous avez posté l'erreur se produit-elle?


L'erreur apparaît sur setTimeout (() => { si HotkeyToggle est évalué comme vrai. Il doit s'agir du numéro de ligne 56


Je crois que votre HotkeyToggle est nul lorsque le perform () est appelé à partir de la fonction setTimeout () .


Utilisez les outils de développement pour définir des points d'arrêt et déboguer le problème, c'est l'outil principal pour de tels cas qui sont généralement résolus en quelques secondes. Le message d'erreur indique que quelque chose à l'intérieur de perform () est nul ou non défini, donc je suppose que vous n'avez pas publié tout le code qui se trouve derrière "// faire des choses ..."


Je pense que cela peut en fait être une erreur dans le moteur Javascript avec une utilisation récursive de SetTimeouts . Il semble que la fermeture de la fenêtre puisse être perdue si pendant certains types de récursivité, par exemple je redéfinissais la fonction qui a appelé SetTimeout () plusieurs fois, parfois de manière récursive et il semble comme un problème de gestion de la mémoire parce que je reçois une erreur indiquant que SetTimeout est nul comme ça, mais seulement en apparence au hasard.


Jusqu'à présent, l'utilisation de window.SetTimeout () a fonctionné pour moi.


3 Réponses :


4
votes

Il s'agit soit d'un problème spécifique à TamperMonkey, soit d'une nouvelle politique / bogue de sécurité dans Chrome lui-même - j'ai rencontré le même problème et l'ai détecté dans le débogueur, et aucun des arguments n'est nul / non défini; setTimeout n'est pas remplacé.

Edit: Un trait partagé entre le usercript en question et celui que je déboguais est l'utilisation "récursive" de setTimeout. Je l'ai changé pour être un setInterval à la place, et cela semble l'avoir corrigé dans mon cas. entrez la description de l'image ici


0 commentaires

2
votes

J'ai eu le même problème avec Tampermonkey et Google Chrome. Ce qui a fonctionné pour moi a été d'utiliser window.setTimeout au lieu de setTimeout .


0 commentaires

3
votes

Il s'agit d'un bogue confirmé dans Chrome:

Signalé sur TM github

Signalé sur bugs.chromium.org a>

Une autre solution qui semble fonctionner est de .bind les fonctions à window , par exemple:

window.clearTimeout = window.clearTimeout.bind(window);
window.clearInterval = window.clearInterval.bind(window);
window.setTimeout = window.setTimeout.bind(window);
window.setInterval = window.setInterval.bind(window);


0 commentaires