javascript - SetimeOut interval fails with "Cannot convert undefined or null to object" - Stack Overflow

I'm getting into user scripting with tampermonkey and can't get through this error, any help

I'm getting into user scripting with tampermonkey and can't get through this error, any help would be appreciated.

I detect keys fine, space key triggers this function who will repeat itself as long as the key remains in the down position. The console writes the output normally for 30 seconds more or less and then there's a TypeError.

As per reputation-restriction, here's a screenshot:

User-Script:

// ==UserScript==
// @name         TEST STUFF--------------------
// @namespace    /
// @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 pletes
        {
            setTimeout(() => {
                perform()
            }, 280);
            return 0
        }
        return 1
    }
} ) ();

I'm getting into user scripting with tampermonkey and can't get through this error, any help would be appreciated.

I detect keys fine, space key triggers this function who will repeat itself as long as the key remains in the down position. The console writes the output normally for 30 seconds more or less and then there's a TypeError.

As per reputation-restriction, here's a screenshot:

User-Script:

// ==UserScript==
// @name         TEST STUFF--------------------
// @namespace    http://tampermonkey/
// @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 pletes
        {
            setTimeout(() => {
                perform()
            }, 280);
            return 0
        }
        return 1
    }
} ) ();

Share Improve this question edited Mar 24, 2019 at 23:45 Praveen Kumar Purushothaman 167k27 gold badges213 silver badges260 bronze badges asked Mar 24, 2019 at 23:39 Cristian Solorio CorderoCristian Solorio Cordero 635 bronze badges 6
  • 3 Which line of the code you posted does the error occur on? – CertainPerformance Commented Mar 24, 2019 at 23:40
  • The error appears on the setTimeout(() => { if the HotkeyToggle evaluates as true. Should be line number 56 – Cristian Solorio Cordero Commented Mar 24, 2019 at 23:44
  • i believe your HotkeyToggle is null when the perform() is called from the setTimeout() function. – Bagus Tesa Commented Mar 24, 2019 at 23:51
  • Use devtools to set breakpoints and debug the problem, this is the primary tool for such cases which are usually solved in a couple of seconds. The error message says that something inside perform() is null or undefined so I'm assuming you didn't post the entire code that's behind "//do stuff..." – woxxom Commented Mar 25, 2019 at 10:06
  • I think this may actually be an error in the Javascript engine with recursive use of SetTimeouts. It seems the closure on window can be lost if during certain types of recursion, for instance I was redefining the function that called SetTimeout() several times, sometimes recursively and it seems like a memory management problem because I receive an error indicating SetTimeout is null like this, but only seemingly randomly. – Motomotes Commented Jun 6, 2019 at 18:27
 |  Show 1 more ment

3 Answers 3

Reset to default 4

This is either a TamperMonkey-specific issue, or a new security policy/bug in Chrome itself - I've ran into the same thing and caught it in the debugger, and none of the arguments are null/undefined; setTimeout is not overriden.

Edit: A shared trait between the userscript in question and the one that I was debugging is the "recursive" use of setTimeout. I changed it to be a setInterval instead, and that seems to have fixed it in my case.

This is a confirmed bug in Chrome:

Reported on TM github

Reported on bugs.chromium

Another solution which looks to work is to .bind the functions to window, eg:

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

The bug should be fixed in Chrome 75.

I had the same issue using Tampermonkey and Google Chrome. What worked for me was using window.setTimeout instead of setTimeout.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745607042a4635730.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信