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.