Using JavaScript generators in Node.js _javascript tips

Source: Internet
Author: User
Tags generator readfile

Generators is a collaborative program of JavaScript (coroutine abbreviation: coprocessor) style, which is a function that can be paused and then restored at execution time, which is functi with an asterisk symbol form such as function*, There are some characteristic keywords in the function such as yield and yield*.

function* Generatorfn () {

 console.log (' Look ma I am suspended ')

}

var generator = GENERATORFN ()//[1]

s Ettimeout (function () {

 generator.next ()//[2]

}, 2000)

The explanations for [1] and [2] annotated in the code are as follows:

1. This is a generator starting with a moratorium. There is no console output at this time.

2. By calling its next () method, the generator executes, runs until it touches the next yield keyword or return, and now we have the console output.

Look at one more case:

function *generator () {

 console.log (' start! ');

 var i = 0;

 while (true) {

  if (I < 3)

   yield i++

 }

}
var gen = generator ();

The above code is similar to the first, but in the generator function more yield keyword, the above code is called, not immediately execute, but suspend standby state, so there will be no start output. Until its next () call is executed.

var ret = Gen.next ();

start!

Console.log (ret);

{value:0, Done:false}

The above RET is the generator result. It has two properties:

Value, the yield in the generator function,

Done, this is an identifier that indicates whether the generator function returns.

Continue the code as follows:

Console.log (Gen.next ());

{value:1, done:false}

Console.log (Gen.next ());

{value:2, done:false}

Console.log (Gen.next ());

{value:undefined, done:true}

Generator is not a mystery in synchronous programming, especially for asynchronous programming.

Generator has two features:

1. You can choose to jump out of a function and let the external code decide when to jump back to the function.
2. Ability to perform asynchronous control.

Look at the following asynchronous code execution:

var gen = generator ();

Console.log (Gen.next (). value);

settimeout (function () {

 console.log (Gen.next (). value);

 Console.log (' first step ');

}, 1000);

Console.log (' second Step ');

The output is:

0
Second Step
1
First step

That is, the settimeout here will not wait for the time to end, but to continue the "second step", will not be blocked in the settimeout.

And look at another piece of code:

function* Channel () {

 var name = Yield ' Hello, what is your name? '//[1] return

 ' OK hi there ' + name

}
   var Gen = Channel ()

Console.log (Gen.next (). Value)/Hello, what is your name? [2]

Console.log (Gen.next (' Billy '))//OK Hi there Billy [3]

You can also use the * when traversing:

function* iter () {for

 (var i = 0, i < i++) yield i} for

(var val of Iter ()) {

 Console.log (val) Outputs 1?—? 9

}

A common misconception

Now that I can suspend a function execution, do you want them to execute in parallel? No, because JavaScript is a single-threaded, if you want to seek to improve performance, generator is not your dish.

For example, the following code executes the Fibonacci number separately:

function fib (n) {

 var = 0, next = 1, swap for

 (var i = 0; i < n; i++) {

  swap = current, current = Next

  next = swap + next

 } return current

}

 

function* Fibgen (n) {

 var current = 0, next = 1, swap< C10/>for (var i = 0; i < n; i++) {

  swap = current, current = next

  next = swap + next

  yield

 current }

}

Performance results are as follows: (the higher the better)

Results
Regular 1263899
Generator 37541

Generators Flash Highlights

Generators can simplify the complexity of functions in JavaScript.

Lazy assigned value

Lazy assignment can be implemented using JS closures, but using yield can be a great simplification, by pausing and resuming, we can get the value when we need it, such as the Fibgen function above can pull the new value when we need it:

var fibiter = Fibgen

var next = Fibiter.next ()

console.log (next.value)

settimeout (function () {

 var next = Fibiter.next ()

 console.log (next.value)

},2000)

Of course also uses a For loop: Still lazy assignment for

(var n of Fibgen (20) {

 console.log (n)

}

Infinite sequence

Because it can be lazy to assign value, then may perform some Haskell tricks, similar infinite sequences. This can yield the number of an infinite sequence.

function* Fibgen () {

 var = 0, next = 1, swap while

 (true) {

  swap = current, current = next

  ne XT = swap + next

  yield current

 }

}

Let's look at the lazy assignment of a Fibonacci stream, asking it to return the first Fibonacci number after 5000:

for (Var num to Fibgen ()) {

 if (num > 5000) Break

}

console.log (num)//6765

Asynchronous Process Control

Using generators to implement asynchronous process control, the most common is the various promise library packages, then how does it work?

In the node area, everything is about callbacks, and this is our low-level asynchronous capability, and we can use generators to build a communication channel to write asynchronous code using the style of synchronized programming.

Run (function* () {

 console.log ("starting")

 var file = yield ReadFile ("./async.js")//[1]

 Console.log ( File.tostring ())

})

Note 1 indicates that the program will continue after waiting for Async.js to return the results.

Genify is a framework for bringing generators into the normal programming environment, using the following:

NPM Install genify is installed with the following code:

var Q = require (' q ');

var fs = require (' FS ');

var genify = require (' genify ');

 

Wrap your object into Genify function

var object = genify ({

 concatfiles:function * (File1, file2, outfile) {
   file1 = Yield Q.nfcall (fs.readfile, file1);

  File2 = Yield Q.nfcall (fs.readfile, file2);

  var concated = file1 + file2;

 

  Yield Q.nfcall (Fs.writefile, outfile, concated);

 

  return concated;

 }

});

 

Concatfiles is a generator function that uses generator power.

object.concatfiles ('./somefile1.txt ', './somefile2.txt ', './concated.txt '). Then (function (res) {

 //Do Something with result

}, function (err) {

 //does something with error

});

The above article in the Node.js use JavaScript generators detailed explanation is small series share to everybody's content, hoped can give everybody a reference, also hoped that everybody supports the cloud habitat community.

Related Article

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.