English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

JavaScript Learning Notes: Application of setTimeout

setTimeou的t应用

var ids = [];
function foo1(i) {
  
  console.log('i = '+i);
  ids[0] = setTimeout((function () {
    foo1(i);
  }),1000);
}
function foo2(j) {
  
  console.log('j = '+j);
  ids[1] = setTimeout((function () {
    foo2(j);
  }),1000);
}
foo1(2);
foo2(3);
clearTimeout(ids[0]);
1]

When setTimeout(f, n) is called, it returns an ID identifier and plans to call the f function in the future about n milliseconds later. The f function will only be executed once (recursive execution can achieve every n milliseconds), based on the timing strategy of the JavaScript engine and its inherent single-threaded execution mode, so the execution of other code may block this thread. Therefore, it cannot be guaranteed that the function will be called at the specified time by setTimeout. Use setTimeout in the callback function to prevent blocking!

JavaScript is asynchronous, and setTimeout will only execute the callback function once, while setInterval will execute the function once every X milliseconds. However, it is not encouraged to use this function. When the execution of the callback function is blocked, setInterval will still issue more callback instructions. In very small time intervals, this can lead to the accumulation of callback functions.

setTimeout and setInterval also accept the first parameter as a string. This feature should never be used, as it internally uses a hidden eval, and since eval is not called directly in this case, the string passed to setTimeout will be executed from the global scope. It is recommended not to use string format when calling timer functions to pass parameters to callback functions; when it is necessary to pass parameters to callback functions, you can create an anonymous function and execute the actual callback function inside it;

Events such as onscroll, onresize are very performance-intensive. If we replace them with AJAX requests, then a window resize will trigger multiple AJAX requests in a row. Let's try using the function throttling operation; of course, adding a setTimeout() timer would be fine.

First encapsulation method

var count = 0;
function oCount() {
  count++;
  console.log(count);
}
window.onresize = function () {
  delayFun(oCount)
});
function delayFun(method, thisArg) {
  clearTimeout(method.props);
  method.props = setTimeout(function () {
    method.call(thisArg)
  }, 200)
}

Second encapsulation method

Construct a closure to form a private scope for the timer 'timer' using the closure method, which is introduced through passing parameters.

var count = 0;
function oCount() {
  count++;
  console.log(count);
}
var funs = delayFun(oCount,100);
window.onresize = function () {
  funs()
});
function delayFun(func, wait) {
  var timer = null;
  return function () {
    var context = this;
      args = arguments;
    clearTimeout(timer);
    timer = setTimeout(function () {
      func.apply(context, args);
    }, wait)
  });
}

Optimize the second method, and the performance will be better

Here returns a function that will not be executed if it is called continuously. The function will only be executed again after stopping the call for N milliseconds. If the 'immediate' parameter is passed, the function will be scheduled to execute immediately without delay.

function delayFun (func, wait, immediate) {
  var timeout;
  return function() {
    var context = this, args = arguments;
    var later = function() {
      timeout = null;
      if (!immediate) func.apply(context, args);
    });
    var callNow = immediate && !timeout;
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
    if (callNow) func.apply(context, args);
  });
});
// Usage
var myEfficientFn = delayFun(function() {
  // All heavy operations
}, 250);
window.addEventListener('resize', myEfficientFn);

Functions do not allow callback functions to be executed more than once within the specified time. When a callback function is assigned to an event that triggers frequently, this function is particularly important.

So powerful is setTimeout, can we use it a lot in the project?

I personally do not recommend it. In our business, we basically prohibit the use of setTimeout in business logic, because many of the usage methods I have seen are some problems that are difficult to solve, and setTimeout as a hack method.

For example, when an instance has not been initialized yet, we use this instance, and the wrong solution is to add a setTimeout when using the instance to ensure that the instance is initialized first.

Why is it wrong? Here it is actually using the hack method.

The first is that it has laid a pitfall, disrupting the module's lifecycle.

The second is that when problems occur, setTimeout is actually very difficult to debug.

I think the correct way to use it is to look at the lifecycle (you can refer to 'About the Software Lifecycle'), and move the instantiation to be executed before use.

That's all the content of the JavaScript learning notes整理_setTimeout application brought to you by the editor. I hope it will be helpful to everyone, and please support the Shouting Tutorial~

You May Also Like