【问题标题】:SetimeOut interval fails with "Cannot convert undefined or null to object"SettimeOut 间隔因“无法将未定义或空值转换为对象”而失败
【发布时间】:2019-03-24 23:39:26
【问题描述】:

我正在使用 Tampermonkey 编写用户脚本,但无法解决此错误,我们将不胜感激。

我很好地检测到键,空格键触发此功能,只要键保持在向下位置,它就会重复。控制台正常写入输出 30 秒或多或少,然后出现 TypeError。

根据声誉限制,这是一个屏幕截图:

用户脚本:

// ==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
    }
} ) ();

【问题讨论】:

  • 您发布的代码的哪一行出现错误?
  • 如果 HotkeyToggle 的计算结果为真,则错误出现在 setTimeout(() => { 上。应该是第 56 行
  • perform()setTimeout() 函数调用时,我相信你的HotkeyToggle 为空。
  • 使用 devtools 设置断点和调试问题,这是通常在几秒钟内解决的这种情况的主要工具。错误消息表明 perform() 中的某些内容为 null 或未定义,因此我假设您没有发布“//do stuff...”后面的整个代码
  • 我认为这实际上可能是递归使用SetTimeouts 的Javascript 引擎中的错误。如果在某些类型的递归期间,window 上的关闭似乎可能会丢失,例如,我重新定义了多次调用 SetTimeout() 的函数,有时是递归的,这似乎是一个内存管理问题,因为我收到一个指示 @ 的错误987654329@ 是这样的 null,但只是看似随机的。

标签: javascript userscripts tampermonkey


【解决方案1】:

这要么是特定于 TamperMonkey 的问题,要么是 Chrome 本身的新安全策略/错误 - 我遇到了同样的事情并在调试器中捕获了它,并且没有一个参数是 null/undefined; setTimeout 未被覆盖。

编辑:有问题的用户脚本和我正在调试的用户脚本之间的一个共同特征是 setTimeout 的“递归”使用。我把它改成了setInterval,这似乎在我的情况下已经解决了。

【讨论】:

    【解决方案2】:

    这是 Chrome 中已确认的错误:

    Reported on TM github

    Reported on bugs.chromium.org

    另一个看起来可行的解决方案是.bindwindow 的函数,例如:

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

    该错误应该在 Chrome 75 中修复。

    【讨论】:

      【解决方案3】:

      我在使用 Tampermonkey 和 Google Chrome 时遇到了同样的问题。对我有用的是使用window.setTimeout 而不是setTimeout

      【讨论】:

        猜你喜欢
        • 2020-08-04
        • 2021-01-20
        • 2020-03-21
        • 1970-01-01
        • 1970-01-01
        • 2022-01-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多