Node JS CO analysis 1

Source: Internet
Author: User

Reprint Please specify: theviper http://www.cnblogs.com/TheViper

Better to see http://purplebamboo.github.io/2014/05/24/koa-source-analytics-1/.

What is a CO module?

Unlike promise, it is an asynchronous control solution based on the ECMAScript 6 generator of the TJ great God.

Like promise, the asynchronous code written with co is elegant, at a glance, and highly scalable.

Because of the need to ECMAScript 6 environment, we need to download the new version of node. Note, do not go to the official website, the official website is the latest stable version, to http://nodejs.org/dist/under. In addition now the official website version is 0.10.35, need is unstable 0.11.x, as to the specific version number, CO at any time change, with the latest good. Finally, add the--harmony parameter when you run node.

ECMAScript 6 generator?

Like what

function*run () {Console.log ("Step in child generator")varb = Yield ' running '; Console.log (b); Console.log ("Step Out Child generator")}//var rungenerator = run ();function*start () {varA = Yield ' start ';  Console.log (a); Yield*run (); varc = Yield ' end ';  Console.log (c); return' Over ';}varit =start (); Console.log (It.next ());//Object {value: ' Start ', done:false}Console.log (It.next (22));//step in Child generator object {value: ' Running ', done:false}Console.log (It.next (333));//333 Step Out child generator Object {value: ' End ', done:false}Console.log (It.next (444));//444 Object {value: "Over", done:true}

Add * After function to indicate that this is a generator function.

var it=start (), when the code is not started execution. It.next (); an iterator equivalent to Java,python.

Yield is equivalent to a single step entry in a breakpoint Debug. Specific,

The first call to It.next (), the code executes to the first yield declaration where yield ' start ' is not assigned to a variable at this time. Then Console.log returns the return value of It.next (), which is an object that is the value of the yield statement, which can be a string, a function, an object, and so on, this is a string, and done indicates whether the current generator function is executed.

Then there is It.next (22), and at this point the a assignment statement starts executing, and actually yield ‘start‘ returns 22, which is the argument we passed. The breakpoint has been executed until the yield ‘running‘; code stops again. The parameters of the next method will be the return value of the previous yield.

After output 22, continue to yield *run (); The yield ' running '; and then, as above, no assignment statement is executed.

If the yield parameter is generator function, then when the yield generator function is executed, it will not stop stepping in until the innermost input parameter of yield is not generator function.

Change the code above to add a generator function.

function*run1 () {Console.log ("Step in child Generator1")varb = Yield ' running1 '; Console.log (b); Console.log ("Step Out child Generator1")}function*run () {Console.log ("Step in child generator") Yield*run1 ();//Console.log (b);Console.log ("Step Out Child generator")}function*start () {varA = Yield ' start ';  Console.log (a); Yield*run (); varc = Yield ' end ';  Console.log (c); return' Over ';}varit =start (); Console.log (It.next ());//Object {value: ' Start ', done:false}Console.log (It.next (22));//the step in child generator step in the child Generator1 object {value: ' Running1 ', done:false}Console.log (It.next (333));//333 Step out child Generator1 step out child generator Object {value: ' End ', done:false}Console.log (It.next (444));//444 Object {value: "Over", done:true}

This is at a glance.

In addition, if there is return in the generator function, the following breakpoint will no longer work, but step out, return in advance, and return the value as the returned value of the proxy call. This later said co can see what is useful.

CO analysis

The latest Co version is 4.1,co 4.x is based on promise rewrite, slightly aggressive point, which will be said later. Here we first say Co 3.x.

First look at an example,

varCO = require (' Co ');varFS = require (' FS ');functionsize (file) {return function(FN) {fs.stat (file,function(err, stat) {if(ERR)returnfn (ERR); FN (NULL, stat.size);  }); }}function*foo () {varA = yield size (' node_modules/thunkify/.npmignore '); varb = yield size (' node_modules/thunkify/makefile '); varc = yield size (' Node_modules/thunkify/package.json '); return[A, B, c];} Co (function*(){  varResults = yield *foo (); Console.log (results);//[13,99,1201]  returnresults;}) ();

Size () is an asynchronous operation that reads the size of the file and then returns.

The size () Here is rewritten, like the deffered in jquery, which needs to be rewritten in a certain form to be used. This form is called thunk, which is one of the parameters that yield can accept in Co.

Acceptable parameter forms

There is a module that can help us make such a rewrite, that is thunkify. As to why it should be rewritten in this form, the following source analysis can see the reason.

Parameter can also accept array

Co (function *() {  var a = Size ('. Gitignore ');   var b = Size (' index.js ');   var c = size (' Makefile ');   var res = yield [A, b, c];  Console.log (res);   // = [1687, 129]}) ()

Object

Co (function *() {  var user = yield {    name: {      first:get (' Name.first ') ),      last:get (' name.last ')    }  };}) ()

Generator

 function  *foo () { var  A = yield size (' Node_modules/thunkify/.npmignore ' );  var  b = yield size (' node_modules/thunkify/makefile ' );  var  c = yield size (' Node_modules/thunkify/package.json ' );  return   [A, b, c];} Co ( function  * () { var  results = yield *foo (); Console.log (results);  // [13,99,1201]   results;}) ();

Promise

Co (function* () {  var result = Yield Promise.resolve (true);   return result;}). Then (function  (value) {  function  (err) {  Console.error ( Err.stack);});

Promise is the object of its own construction.

In addition, nesting is supported for all allowed parameter forms above.

function*foo () {varA = yield size ('. Gitignore ')); varb = yield size (' Makefile '); varc = yield size (' Package.json '); return[A, B, c];}function*Bar () {varA = yield size (' examples/parallel.js '); varb = yield size (' examples/nested.js '); varc = yield size (' examples/simple.js '); return[A, B, c];} Co (function*(){  varResults =yield [foo (), bar ()]; Console.log (results);}) ()

If there's a callback.

function*foo () {varA = yield size (' node_modules/thunkify/.npmignore '); varb = yield size (' node_modules/thunkify/makefile '); varc = yield size (' Node_modules/thunkify/package.json '); return[A, B, c];} Co (function*(){  varResults = yield *foo ();  Console.log (results); returnresults;}) (function(Err,args) {console.log (args);});

As you can see, two parameters are passed to the callback, one is the error message and the other is an array of return values. This is defined in size ().

function size (file) {  returnfunction(FN) {    function(err, stat) {       if return fn (err);      FN (null, stat.size);}    );}  }

The FN inside is the callback the back co is going to perform. If it becomes FN (stat.size), then there is only one argument.

functionsize (file) {return function(FN) {fs.stat (file,function(err, stat) {if(ERR)returnfnNULL);    FN (stat.size);  }); }}co (function*(){  varResults = yield *foo ();  Console.log (results); returnresults;}) (function(args) {console.log (args);// -});

Only the result of the first asynchronous operation is returned. Because the co specifies that the callback allows only the two parameters that were said to be passed in. If the result of an asynchronous operation is more than one value.

functionsize (file) {return function(FN) {fs.stat (file,function(err, stat) {if(ERR)returnfn (ERR); FN (NULL, Stat.size,stat.atime);  }); }}function*foo () {varA = yield size (' node_modules/thunkify/.npmignore '); varb = yield size (' node_modules/thunkify/makefile '); varc = yield size (' Node_modules/thunkify/package.json '); return[A, B, c];} Co (function*(){  varResults = yield *foo ();  Console.log (results); returnresults;}) (function(Err,args) {console.log (args);});

You can see that the result is added to an array.

Node JS CO analysis 1

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.