settimeout not working properly when i tried to use it to refresh a page

Tags: , , , ,



The purpose of this code is to refresh a page after either a wait time of 1 second or 5 seconds depending on a random variable. However, the code below makes it so that it either refreshes after a wait time of 1 second EVERY SINGLE TIME, or it refreshes after a wait time of 5 seconds EVERY SINGLE TIME.

How do I make it so that the refresh wait time are EITHER 1 second OR 5 seconds on every refresh?

// ==UserScript==
// @name        google.com
// @namespace   John Galt
// @description Basic Google Hello
// @match       *^https://www.google.com/$*
// @version     1
// @require     https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js
// @grant       GM_xmlhttpRequest
// @run-at document-end
// ==/UserScript==

//*****************************************START OF SET_TIMEOUT
(function ($) {
  'use strict';
  var interval;
  if (Math.floor(Math.random() * 2) == 0) { interval = 1000; }
  else { interval = 5000; }
  if (window == window.top) {
    var body = $('body').empty();
    var myframe = $('<iframe>')
      .attr({ src: location.href })
      .css({ height: '95vh', width: '100%' })
      .appendTo(body)
      .on('load', function () {
        setTimeout(function () {
          myframe.attr({ src: location.href });
        }, interval);
      });
  }
})(jQuery);
//*****************************************END OF SET_TIMEOUT

Answer

The issue is that while you are pointing the iframe to the current document, the document that contains the iframe is only being loaded once (and that’s why you are seeing the same interval being used over and over) and when the iframe loads the same file up inside of it, the value that it generates for interval is not the same one as is controlling the loading of the iframe.

I think you should just do an AJAX request for the current file inside of your setTimeout. That way you can handle a server error by just doing the AJAX call again. This would be way simpler. No iframe.

(function ($) {
 'use strict';

 // Store possible delay values in an array
 var possibleDelays = [1000, 5000];
      
 function reload() {
   $.ajax(location.href)
    .done(function () {
       $("h1").text(new Date().toLocaleTimeString());
       // Success! Do it again!
       setTimeout(reload, possibleDelays[Math.round(Math.random())]);
    }).fail(reload); // When there's an error, try again
  }

  // Initiate the process with an interval that is generated right here.
  setTimeout(reload, possibleDelays[Math.round(Math.random())]);
})(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1></h1>


Source: stackoverflow