📜 ⬆️ ⬇️

Coroutine implementation in NodeJS

The output of iojs encouraged me to study functions that have already become stable in v8, in particular, native promises and generators that can be turned into corutines. I was surprised that on Habré there is no article devoted to how to do another implementation of coroutine yourself through generators and understand what actually happens in co / bluebird. To start using without fear of the magic of coroutine I ask for cat.


Coroutine (coroutine) is a function (program) having several input points. You can stop it at a certain point, do something else, and then return to this point again and continue with new data (not necessarily with new data but with the same condition as it was). Fiber is one of the implementation of korutin for nodejs (for example, node-fibers ), but now we are talking about implementation without writing a plugin in C ++ or metaprogramming, using only native Javascript methods.


In particular, Korutin give us the opportunity to write similar code:
function timeout(ms, msg){ return new Promise(function(resolve, reject){ setTimeout(function(msg){ console.log(msg); resolve(msg); }, ms, msg); }); } var makeJob = function *(){ yield timeout(1000, 1); yield timeout(1000, 2); var user = yield getUser(); return user.info; }; generatorWrapper(makeJob); 

')
It turns out quite briefly and more clearly. Instead of timeout, there can be any other function that can do promises, for example, it follows the data to the database and returns the data directly to the same function, and not to then / callback, which is quite convenient, since allows and cancels the execution of sequential asynchronous functions more conveniently than is possible in the promise chain.
The whole point of the question is what this generatorWrapper looks like. And this is my reasoning on this.
 function async(gen){ var instance = gen(); //  ,     return new Promise(function(resolve, reject){ //       function next(r){ if (r.done) { resolve(r.value);//     resolve'  . } if (typeof(r.value.then)=='function')//  duck typing, ..   Promise   { r.value.then(function(someRes){ next(instance.next());// next    . }, function(e){ reject(e); }); } else { console.log(r.value); next(instance.next()); } } next(instance.next());//       }); } 

This implementation is ideological to understand how it all works, but the ideology is about the same in co and bluebird.
Of course, full-fledged implementations are co and bluebird.coroutine , they have parallel processing and the possibility of advanced processing, including working with other generators.

From the code you can see that the generator in JS, although it allows you to write the code of the form as Korutiny, but in fact is not intended for this. Generator, sorry for captaincy and tautology, first of all the generator and most conveniently on it all the same to do lazy calculations, and using it in this way is not quite its intended purpose, although according to my tests I did not notice any performance degradation.
On the other hand, it is clear when looking at future standards such as await / async , that everything is not so far in principle, it is possible to safely use current generation-based Korutines using iojs + co / bluebird without fear for the stability of the product. And considering that all the correct implementations of Corutin return the native promise, then all this is completely compatible with the upcoming standards.

I summarize: calmly put and use it in iojs. In the code written on promises, all this rises without any changes. If you want to add something to the functional, you can look at the same co and add something of your own, there is nothing wrong with this processing. If you want to make an async race, do not deny yourself this, but then you have to do it in another function on promises, not a generator, or invent your own data format, otherwise feel free with generators, they are now the same part of the standard as everything else .

PS Sorry for the raw material, I hope for your help to improve it.

Source: https://habr.com/ru/post/253347/


All Articles