Uncaught TypeError: Cannot read property 'length' of undefined myTimer

Uncaught TypeError: Cannot read property 'length' of undefined myTimer

我有一个网站,它有一个表单,用户可以在其中输入他们的电子邮件,并在提交后发送到下一页。当我在此页面上输入电子邮件并分析控制台时,我看到以下异常:

Uncaught TypeError: Cannot read property 'length' of undefined myTimer @ VM567 content.js:43(anonymous function) @ VM567 content.js:40

当我点击它时,我看到 content.js 为:

var gtmSnippet = document.createElement('script');
gtmSnippet.title = 'TMI-INJECTED-GTM-CONTAINER-SNIPPET';
gtmSnippet.id = 'tmigtmsnippet';

var gtmTrigger = document.createElement('div');
gtmTrigger.id = 'tmitriggerholder';

var THEID;   

function DB_setValue(name, value, callback) {
    var obj = {};
    obj[name] = value;
    console.log("Data Saved!");
    chrome.storage.local.set(obj, function() {
        if(callback) callback();
    });
}
    
chrome.runtime.sendMessage({greeting: "SnippetPlease"}, function(response) {
    THEID = response.farewell;
    if(response.farewell.length > 0){
        gtmSnippet.text = "//GTM CONTAINER INJECTION: \n(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src='//www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);})(window,document,'script','dataLayer','" + response.farewell + "'); \n//GTM CONTAINER INJECTION ENDS\n";
        
        // Get a value saved in a form.
        var theValue = THEID;
        // Check that there's some code there.
        if (!theValue) {
            return;
        }
        else{
            DB_setValue('theid',theValue,function(){});
        }
    }
});  

40 var interval = setInterval(function(){myTimer()}, 0.1);

41 function myTimer() {
42    if((document.body != null) && (THEID.length>0)){
43      // INJECT CONTAINER SNIPPET
44      document.body.appendChild(gtmSnippet);
45      
46      stopInterval();
47  }
}

function stopInterval() {
    clearInterval(interval);
}

我刚刚开始修改 JavaScript,但我不明白为什么会出现此错误,并且

我该如何解决?

函数是同步的

变量THEID在异步函数中赋值:

chrome.runtime.sendMessage({greeting: "SnippetPlease"}, function(response) {
    THEID = response.farewell;
    ..

也就是说会保持undefined直到上面的回调函数收到响应消息

如果你下面的时间间隔(时间间隔太小)试图访问THEID的值,它不能保证响应已经被收到并且 THEID 的值已经设置。所以你遇到了undefined.

var interval = setInterval(function(){myTimer()}, 0.1);

function myTimer() {
   // This function will be executed before the response is received
   // by chrome.runtime.sendMessage()
   if((document.body != null) && (THEID.length>0)){
     ...
     ...

解决此问题的方法?

您可以考虑在响应回调中执行您的逻辑,而不是使用时间间隔来检查。所以你的代码可能会变成:

chrome.runtime.sendMessage({greeting: "SnippetPlease"}, function(response) {
    THEID = response.farewell;
    ..
    ..
    // At this point of time, THEID is set from the response.
    if((document.body != null) && (THEID.length>0)){
        // INJECT CONTAINER SNIPPET
        document.body.appendChild(gtmSnippet);
    }
});

或者换一种方式

短路如果THEID如下未定义:

function myTimer() {
   // This function will be executed before the response is received
   // by chrome.runtime.sendMessage()
   if((document.body != null) && THEID && THEID.length>0)){
       ...
       ...

所以你仍然可以使用你的时间间隔方法,稍加修改。