“This is the 14th day of my participation in the First Challenge 2022.

introduce

I believe that we will see the title of the timer and so on in the web development has been rotten streets, but it is like playing billiards, the more you feel simple things, often the more mistakes and problems are the most. Here are four ways to “manipulate time” and see if you can actually use them.

setTimeout()

It is our most commonly used timer method, which executes a function or a specified piece of code after a certain period of time.

let timer = setTimeout(() = > {
    console.log("Complete")},1000)
Copy the code

It can also be removed:

clearTimeout(timer)
Copy the code

We often see optimizations for anti-shaking also rely on them for implementation:

function debounce(handler, delay) {
    var handler = handler || null;
    var delay = ~~delay || 1000;
    var timer = null;
    return function() {
        clearTimeout(timer)
        timer = setTimeout(function() {
            handler.apply(this.arguments);
        }.bind(this), delay)
    }
}
Copy the code

Also, if we want to execute immediately after the main process has finished executing, we can set the time directly to 0ms, which is very useful when completing certain requirements:

setTimeout(() = >{
    console.log(2);
}, 0);
console.log(1);
Copy the code

setInterval()

Similar to setTimeout, except that it can execute a function or a specified piece of code over a period of time.

let timer = setInterval(() = > {
    console.log("Complete + 1")},1000)
Copy the code

Of course, it can also be removed:

clearInterva(timer)
Copy the code

It’s important to note that setInterval is not as stable as setTimeout, though it’s more like an infinite number of setTimeouts, but it’s not quite. If you want to reduce the error, you can use recursion +setTimeout or requestAnimationFrame instead of setInterval.

requestAnimationFrame()

It is a looping function, especially if animation needs to run efficiently. As we all know, the smoothness of an animation depends directly on the frame rate of the animation and is measured in frames per second (FPS). The higher the number, the smoother the animation looks. In order to meet the necessary condition for us to visually observe whether the animation has frame lag, 60 frames are needed for 1000 milliseconds (note: the screen refresh rate is 60Hz), that is, 1 frame needs 16.7 milliseconds. SetTimeout and setInterval are greatly affected by the performance of the computer itself, and the value of each time is probably not 16.7. RequestAnimationFrame does this, keeping the frame rate relatively constant, and using requestAnimationFrame saves memory. It is currently used in almost every refresh built into the H5 game engine.

Next, see how he uses it.

function step(delta) {
    console.log(delta)
    requestAnimationFrame(step.bind(this));
}
Copy the code

I have just printed the delta, and the difference between two and two will be approximately 16.6 each time. It would be very smooth if you were animating.

In addition, we often have something in the game that generates enemies at intervals, which can be used with timestamps:

let startTime = new Date().getTime()
let endTime = new Date().getTime();
let duration = 800; // Interval period
function step(delta) {
    requestAnimationFrame(step.bind(this))
    render(delta) / / rendering
    if (endTime - startTime > duration) {
        createEnemy() // Generate enemies
        startTime = endTime  // Re-record the time
    }
    endTime = new Date().getTime();
}
Copy the code

We can use this method cycle control screen termination and so on operation, is also very convenient.

Of course, it also has the ability to undo operations:

let timer = requestAnimationFrame(step.bind(this))
cancelAnimationFrame(timer);
Copy the code

In fact, its compatibility is already relatively good, but considering ie10 and Android 4.4 users below, can write a compatible method from the trend down level setTimeout.

window.requestAnimFrame = (function() {
    return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
        function(callback,element) {
            return window.setTimeout(callback, 1000 / 60); }; }) ();Copy the code

sleep()

There are often interview questions about how to make web pages sleep in suspended animation, after all, JS is not Java without this built-in API. So how do you get the Web into suspended animation sleep? In fact, it is not difficult to figure out the solution, because JS is a single thread, so we can use a while loop to block the progress of the page. Activate it at a certain point in time.

Next, we try to implement:

function sleep(time = 1) {
    let startTime = new Date().getTime();
    let nowTime = new Date().getTime();
    while (startTime+time>nowTime) {
        nowTime = new Date().getTime(); }}Copy the code
document.getElementById("btn").addEventListener("click".e= > {
    console.log("I'm going to execute it.".new Date())
    sleep(2000)
    console.log("I'm done.".new Date()})Copy the code

At this time, all the codes under sleep will be blocked and cannot be executed, and the whole web page will become a state of suspended animation sleep, until it is activated again after 2000, and the following codes will be executed successively.