[node. js] ECMAScript 6 Generator and KOA small analysis

Source: Internet
Author: User
Tags readfile install node

Original address: http://www.moye.me/2014/11/10/ecmascript-6-generator/

Introduction

Old listen to people say koa Dafa good, these two days I also rushed to fashion: with N to install node 0.11.12, under a KOA Open Harmony mode test water. In the education of a series of documents and posts, it is probably recognized that:

    • KOA is a new generation of web frameworks dominated by TJ God
    • KOA Middleware is based on the ES6 generator function * Form
    • KOA Core Process Library is co, it can solve pyramid of doom problem very well

Before I contacted node. js, I was already aware of what the generator was about because of the experience of Python programming. What I'm really interested in is how it was used to optimize the callback nesting.

"Why are you so fucking?"

In the KOA framework why is there such a piece in the article (Fragment 1):

varFS = require (' FS ');varApp = require (' KOA ')();varReadFile =function(dir) {return function(FN) {fs.readfile (dir, FN); }}app.use (function* () {  vararr = yield [' 1.txt ', ' 2.txt ', ' 3.txt '].map (function(path) {returnreadFile (path);    });  This. BODY = Arr.join (', ');}) App.listen (8000);

This code is a good example of how KOA uses the Generator function (function* (), the function's constructor.name = = = ' Generatorfunction ') to serialize the asynchronous callback, and its execution flow:

  1. function*(){...} Was made as a generator function push into the KOA middleware queue
  2. KOA uses the CO framework to execute calls to the generator function, and the generator function does not immediately execute the function body, but instead generates the generator (generator) instance--and the generator can be treated as an instance of the iterator protocol, and each time the next () of the iterator is called, it will return a { value: obj, done:true/false } Object: Value is the execution result value, done indicates whether the iteration is complete
  3. The next () method that invokes the generator instance launches the execution flow inside the function body until yield is suspended, and next next () will give yield the resulting value of execution and suspend at the next yield occurrence; it can be understood that yield always returns to the previous next () result value, if Next () has parameters, yield returns this parameter value (async callback has the opportunity to inject the execution result)
  4. Observing the code snippet above, we notice that ReadFile's callback handler is not provided in the FN code, so what does KOA or co do with the callback function? In Koa (0.13.0), the following fragment (fragment 2) can be seen in the Co source code (LINE:84):
    //NormalizeRet.value =Tothunk (Ret.value, CTX);//Runif(' function ' = =typeofret.value) {varcalled =false; Try{ret.value.call (CTX,function(){      if(called)return; Called=true;    Next.apply (CTX, arguments);  }); } Catch(e) {setimmediate (function(){      if(called)return; Called=true;    Next (e);  }); }  return;}

  5. the tothunk is converted into a standard function based on the expression returned by yield (fragment 3):
    functiontothunk (obj, ctx) {if(isgeneratorfunction (obj)) {returnCo (Obj.call (CTX)); }  if(Isgenerator (obj)) {returnCo (obj); }  if(ispromise (obj)) {returnpromisetothunk (obj); }  if(' function ' = =typeofobj) {    returnobj; }  if(IsObject (obj) | |Array.isarray (obj)) {    returnObjecttothunk.call (CTX, obj); }  returnobj;}

  6. In fragment 1, the generator function first returns a generator, and then the yield binding map returns three function objects, the function returned by the higher-order functions ReadFile:
    function (FN) {    fs.readfile (dir, fn);}

  7. Fragment 2 calls the function and provides a callback function based on the type returned by the Fragment 3: The arguments is next.apply(ctx, arguments); passed smartly. As mentioned earlier, next () if the parameter is provided, the result value of yield is this parameter, and the callback result is thus.
Who the hell is that?

If crossing after reading the above paragraphs are not dizzy, it is your most cock:)-My ability to express is really not enough to clear the framework of the mystery, but in my opinion, the real dick is the ES6 generator mechanism itself.

Temporarily lay down the Co framework, transforming the piece 1 slightly (fragment 4):

varFS = require (' FS ');varPath = require (' path '); varReadFile =function(dir) {return function(FN) {fs.readfile (dir, {encoding:' UTF8 ', flag: ' R '}, FN);    };}; function*readfilegeneratorfunction (Path, CB) {Console.log (yield readFile (path) (CB));} varReadfileiterator = readfilegeneratorfunction (' testdate.js '), callback);functioncallback (err, data) {readfileiterator.next (data);} Readfileiterator.next ();

The intention is obvious:

    1. This readfilegeneratorfunction is a generator function that executes it to return a generator (iterator)
    2. function returned by higher order functions, with callback specified when generator function executes
    3. Next triggers execution
    4. When the callback is complete, next (data) carries the result value to trigger yield

The problem is also obvious that the business code (yield in generatorfunction) needs to be placed before the process Control (callback), which is unscientific. Abstract, you can provide an execution function for a generator function:

function Run (generatorfunction) {    var generatoritr = generatorfunction (callback);     function callback (err, data) {        if(err)            console.log (err);        Generatoritr.next (data);    }    Generatoritr.next ();}

Test it:

Run (function* Rfgenfunc (CB) {    console.log (' first ');    Console.log (Yield readFile (' 1.txt ') (CB));    Console.log (' second ');    Console.log (Yield readFile (' 2.txt ') (CB));});

Execution Result:

Summary

This article only gives a brief description of the next () Application of generator (in fact it has more content such as: Throw/send/close). As for the generator features, it is still in the draft ECMAScript 6 specification, as stated in MDN: Use caution:)

More articles please visit my blog new address: http://www.moye.me/

[node. js] ECMAScript 6 Generator and KOA small analysis

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.