The sleep implementation of JavaScript--javascript asynchronous Programming learning

Source: Internet
Author: User
Tags message queue sleep function

First, the original demand

Recently in the Baidu front-end Technical college exercises, there is a practice is required to traverse a binary tree, and do the traversal visualization is traversing the node the best color is different

The binary tree probably looks like this:

For example, the previous sequence traversal,

Every time you visit a binary tree node, add a sleep.

The author writes that it is this:

1Let root = document.getElementById (' Root-box ');2 3   functionPreorder (node) {4         if(node = = =undefined) {5             return;6         }7Node.style.backgroundColor = ' Blue ';//Start Access8Sleep (500);9Node.style.backgroundColor = ' #ffffff ';//Access CompleteTenPreorder (node.children[0]); OnePreorder (node.children[1]); A     } -  -document.getElementById (' pre-order '). AddEventListener (' click '),function () { the preorder (root); -});

Here's the problem, there's no sleep function in JavaScript!

Second, the realization of settimeout

Understanding the concurrency model of JavaScript eventloop all know that JavaScript is single-threaded and that all time-consuming operations are asynchronous

You can use settimeout to simulate an asynchronous operation using the following:

setTimeout (function() {Console.log (' asynchronous operation performed ');},millisecond);

This means that Console.log executes after millisecond milliseconds, and the first parameter of settimeout is a callback function that executes once after the time specified by the second parameter.

As shown in the stack (stack) is the currently executing function call stacks, and queue (Message Queuing) is the next EventLoop loop to execute the function in turn.

In fact, the function of settimeout is to add the callback function to the end of the message queue after a specified time, and if there are no other messages in the queue, the callback executes directly. That is, the time parameter of the settimeout only represents the minimum amount of time after which execution occurs.

More detailed knowledge about the EventLoop will not be mentioned, interested can learn about Setimmediate and Process.nexttick and settimeout (f,0) The difference

The actual operational visual traversal is written as follows:

Let root = document.getElementById (' Root-box '); Let Count= 1; //Pre-order    functionPreorder (node) {if(node = = =undefined) {            return; }        (function(node) {setTimeout (function() {Node.style.backgroundColor= ' Blue '; }, Count* 1000);        }) (node); (function(node) {setTimeout (function() {Node.style.backgroundColor= ' #ffffff '; }, Count* 1000 + 500);        }) (node); Count++; Preorder (node.children[0]); Preorder (node.children[1]); } document.getElementById (' Pre-order '). AddEventListener (' click ',function() {count= 1;    Preorder (root); });

It can be seen that my train of thought is to change the color of the traverse all into a callback, in order to form the time gap, there is a count variable in the number of traversal increments.

It looks clearer, but it's a lot different from the sleep I was imagining.

Sleep is blocking the current process for some time, so it seems inappropriate in JavaScript, but it can be simulated.

Third, the realization of generator

In the study of the "ES6 Standard Primer" This book, vaguely remember that the generator function has a feature, each execution to the next yield statement, the role of yield is the CPU control to hand over the outside, feel can be used to do sleep.

Write it out like this:

Let root = document.getElementById (' Root-box '); function*Preorder (node) {if(node = = =undefined) {            return; } Node.style.backgroundColor= ' Blue ';//AccessYield ' sleep '; Node.style.backgroundColor= ' #ffffff ';//Delayyield* Preorder (node.children[0]); Yield* Preorder (node.children[1]); }    functionSleeper (millisecond, Executor) { for(Let count = 1; count < count++;) {            (function(Executor) {setTimeout (function() {executor.next (); }, Count*millisecond);        }) (Executor); }} document.getElementById (' Pre-order '). AddEventListener (' click ',function() {Let preorderexecutor=preorder (root); Sleeper (500, Preorderexecutor); });

This kind of code feels strange, compared to the previous settimeout, there seems to be no improvement, or there is a count in increments, and must guide the number of traversal, in order to guide the generator function execution.

Iv. realization of Generator+promise

For the sake of improvement, generator is able to automatically execute once in 500 milliseconds, with the help of the promise resolve function. It should be possible to implement callbacks using the Thunk function, but it seems promise easier to understand.

The idea is that each time delay is a promise, resolve after the specified time, and resolve's callback moves the generator pointer to the next yield statement.

Let root = document.getElementById (' Root-box '); functionSleep (millisecond) {return NewPromise (function(Resolve, Reject) {SetTimeout (function() {Resolve (' Wake ');        }, millisecond);    }); }    function*Preorder (node) {if(node = = =undefined) {            return; } Node.style.backgroundColor= ' Blue ';//AccessYield sleep (500);//returns a Promise objectNode.style.backgroundColor = ' #ffffff ';//Delayyield* Preorder (node.children[0]); Yield* Preorder (node.children[1]); }    functionExecutor (IT) {functionRunner (result) {if(result.done) {returnResult.value; }            returnResult.value.then (function(Resolve) {runner (It.next ());//called after resolve},function(reject) {Throw NewError (' Useless error ');        });    } runner (It.next ()); } document.getElementById (' Pre-order '). AddEventListener (' click ',function() {Let preorderexecutor=preorder (root);    Executor (preorderexecutor); });

It looks like the original demand for sleep, but it needs to write a generator actuator.

V. Implementation of Async

The standard of the ES update is that ES7 has an async function, and the async function has a built-in generator executor, just write the generator function yourself.

Let root = document.getElementById (' Root-box '); functionSleep (millisecond) {return NewPromise (function(Resovle, Reject) {SetTimeout (function() {Resovle (' Wake ');        }, millisecond);    }); } AsyncfunctionPreorder (node) {if(node = = =undefined) {            return; } Let Res=NULL; Node.style.backgroundColor= ' Blue '; Await Sleep (500); Node.style.backgroundColor= ' #ffffff '; Await preorder (node.children[0]); Await preorder (node.children[1]); } document.getElementById (' Pre-order '). AddEventListener (' click ',function() {preorder (root); });

Probably only this step, sleep (500) The preceding await indicates that this is an asynchronous operation.

But I prefer the following wording:

Let root = document.getElementById (' Root-box '); functionVisit (node) {Node.style.backgroundColor= ' Blue '; return NewPromise (function(Resolve, Reject) {SetTimeout (function() {Node.style.backgroundColor= ' #ffffff '; Resolve (' Visited '); }, 500);    }); } AsyncfunctionPreorder (node) {if(node = = =undefined) {            return; }await visit (node);await preorder (node.children[0]); Await preorder (node.children[1]); } document.getElementById (' Pre-order '). AddEventListener (' click ',function() {preorder (root); });

No longer entangled in the implementation of the sleep function, visit more in line with the reality of the situation, access to the node is a time-consuming operation. The entire code looks clear and understandable.

After this study, I realized the idea of JavaScript async, so the concept of a direct hard set of C language sleep is inappropriate, the world of JavaScript is an asynchronous world, and Async appears in order to better organize the writing of asynchronous code, the idea is still asynchronous

In the next rookie, the article what is wrong in the place also please enlighten

Reference documents:

1, "The ES6 Standard Introduction"

2. JavaScript concurrency model and event Loop:https://developer.mozilla.org/zh-cn/docs/web/javascript/eventloop

JavaScript's Sleep Implementation--javascript asynchronous programming learning

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.