Preface: The author already had questions before he came into contact with the business with countdown requirements. How is the countdown plate implemented on various seckill platforms? During the internship in Ali, the business met the business demand of realizing the countdown plate, so I sorted it out.
What’s my problem?
The key to the confusion is the EventLoop mechanism in JS. If you are not familiar with this part, please refer to my previous article: Vernacular EventLoop.
As we all know, task queue is an important part of JS code execution mechanism. Macro tasks represented by setTimeout setInterval are first-class citizens in the task queue. Obviously, the countdown function should be implemented by setInterval. However, according to EventLoop, setInterval’s callback is inserted at the end of the queue at the expected time, rather than executed directly. By this logic, if the first macro task takes too long to execute (even if it takes too long to execute, but just before the setInterval callback), it will affect the timer timing!
Verify the guess
First, we start a timer on the console
let counter = 10000;
setInterval(() = >{
console.log(`counter: ${counter--}`)},1000)
Copy the code
Then declare a sleep function to block the thread as a macro task.
function sleep(delay) {
var start = (new Date()).getTime();
while((new Date()).getTime() - start < delay) {
continue; }}Copy the code
At this point our console should be counting down continuously: 100009999… Execute Sleep (2000) at this point, and you can see that the countdown in the console stops for two seconds and then continues counting down.
To sum up, we can see that the essence of Sleep (2000) only simulates the execution of synchronous code, and macro tasks in real business scenarios are unlikely to block threads for such a long time. But even a 0.1 second block will affect the countdown.
In addition, other macro tasks, such as UI rendering, callback of network requests, and so on, follow the same mechanism and can block the countdown.
How to solve this problem in service scenarios?
- In non-seckill, panic buying and other scenarios with strong time accuracy requirements, we try our best to simplify the logic of the page and prevent various operations from affecting the accuracy of the timer.
- In the scenario of seckilling and buying, time accuracy can be jointly maintained by using the way of collaboration with the back end. Specific methods are as follows:
- It communicates with the back end at regular intervals, like sending a heartbeat, and maintains time accuracy through polling.
- Bind time synchronization requests to events corresponding to various user operations. Like clicking a button…
- If there is a better solution to supplement.
The latter
After asking my brother, I learned that the above method has been applied to the best practice of various Ali promotion ~ this also reflects the JS language in some aspects of the pull down ha ha ha ha ha ha