谷歌分析hitCallback超时

时间:2016-06-24 00:28:52

标签: javascript google-analytics

我正在查看Google Analytics Guides,看到了这段代码:

// Gets a reference to the form element, assuming
// it contains the id attribute "signup-form".
var form = document.getElementById('signup-form');

// Adds a listener for the "submit" event.
form.addEventListener('submit', function(event) {

  // Prevents the browser from submiting the form
  // and thus unloading the current page.
  event.preventDefault();

  // Sends the event to Google Analytics and
  // resubmits the form once the hit is done.
  ga('send', 'event', 'Signup Form', 'submit', {
    hitCallback: function() {
      form.submit();
    }
  });
});

然后它说“如果(无论出于何种原因)analytics.js库无法加载,hitCallback函数将永远不会运行。”它提供了如下解决方案:

// Gets a reference to the form element, assuming
// it contains the id attribute "signup-form".
var form = document.getElementById('signup-form');

// Adds a listener for the "submit" event.
form.addEventListener('submit', function(event) {

  // Prevents the browser from submiting the form
  // and thus unloading the current page.
  event.preventDefault();

  // Creates a timeout to call `submitForm` after one second.
  setTimeout(submitForm, 1000);

  // Keeps track of whether or not the form has been submitted.
  // This prevents the form from being submitted twice in cases
  // where `hitCallback` fires normally.
  var formSubmitted = false;

  function submitForm() {
    if (!formSubmitted) {
      formSubmitted = true;
      form.submit();
    }
  }

  // Sends the event to Google Analytics and
  // resubmits the form once the hit is done.
  ga('send', 'event', 'Signup Form', 'submit', {
    hitCallback: submitForm
  });
});

我可以理解上面的代码。但接下来的事情让我感到困惑:

function createFunctionWithTimeout(callback, opt_timeout) {
  var called = false;
  function fn() {
    if (!called) {
      called = true;
      callback();
    }
  }
  setTimeout(fn, opt_timeout || 1000);
  return fn;
}

// Gets a reference to the form element, assuming
// it contains the id attribute "signup-form".
var form = document.getElementById('signup-form');

// Adds a listener for the "submit" event.
form.addEventListener('submit', function(event) {

  // Prevents the browser from submiting the form
  // and thus unloading the current page.
  event.preventDefault();

  // Sends the event to Google Analytics and
  // resubmits the form once the hit is done.
  ga('send', 'event', 'Signup Form', 'submit', {
    hitCallback: createFunctionWithTimeout(function() {
      form.submit();
    })
  });
});

我的理解是,在最后一段代码中,如果analytics.js库无法加载,则hitCallback函数将不会运行,这意味着setTimeout()将不会运行。因此,最后一段代码似乎没有作为第二块代码的功能。

我错过了什么吗?或者这就是它?

1 个答案:

答案 0 :(得分:1)

我认为首先需要清理的是Google在说hitCallback失败时的含义。他们documentation on the property的这个片段对此有所了解:

  

您可能希望避免使用hitcallBack来执行对您的应用程序至关重要的代码,因为在极少数情况下可能无法调用它(例如,如果服务器没有响应或analytics.js无法加载)。在这种情况下,您可以设置超时以确保执行。

在最初阅读问题后,我想如果ga对象发送命中,那么肯定hitCallback必须工作,这个场景必须是全部或全部。从它的声音来看,谷歌只是警告系统中的罕见昙花一现或在命中发送和回调功能之间发生的模糊加载失败。我从这个陈述中理解的是ga对象总是会使用hitCallback,但是响应永远不会从服务器返回的可能性很小。正是由于这些情况,建议不要使用任务关键代码,具体取决于此属性。

为了解释上面的代码,第2和第3块中的设置实现了不同抽象级别的相同目标。在第二个区块中,我们有一个功能:

function submitForm() {
    if (!formSubmitted) {
      formSubmitted = true;
      form.submit();
    }
  }

在表单的提交事件被触发时,在setTimeout中调用一次,在hitCallback中调用一次。因此,如果后者永远不会得到答复,前者的1秒延迟将提交表格,而不依赖于答案。

第3个块将setTimeout功能包装在首次加载javascript时运行的函数中:

function createFunctionWithTimeout(callback, opt_timeout) {
  var called = false;
  function fn() {
    if (!called) {
      called = true;
      callback();
    }
  }
  setTimeout(fn, opt_timeout || 1000);
  return fn;
}

在这种情况下,{j}被读取时计算createFunctionWithTimeout,传入的函数将在从分析返回时由hitCallback调用,或由{调用}调用{1}}从此之前。

由于setTimeout用作回调,我们可以通过使用事件侦听器回调作为测试来验证这一点。以此代码为例:

hitCallback
// Same function as above
function createFunctionWithTimeout(callback, opt_timeout) {
  var called = false;
  function fn() {
    if (!called) {
      called = true;
      callback();
    }
  }
  setTimeout(fn, opt_timeout || 1000);
  return fn;
}

// The createFunctionWithTimeout will be calculated initially when it loads
// If you don't press the button for 2 seconds, the alert will still pop up
// If you press the button before 2 seconds passes, you'll see the popup earlier
$('#btn').click(createFunctionWithTimeout(function() { 
	alert("Hello!"); 
  }, 2000)
);

因此,无论您使用第二个还是第三个块,都取决于您想要抽象<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script> <input type='button' id='btn' value='test' />功能的程度。谷歌的文档推荐第三种情况,如果你计划大量使用这个功能,因为这会减少复制代码,但最终都会实现目标。