TameJS - taming asynchronous programming
What is TameJS?
TameJS is a Javascript extension that makes event / asynchronous programming easier and more elegant. It is very simple to use with nodejs or other v8 projects.
Simple example
Suppose we have a dating site, and we want to write a handler for the user visiting the user’s page “Buffy” by the user “Angel”.
The algorithm for such a visit is as follows:
- calculate how much Buffy fits Angel (common interests and preferences)
- find the next pair for angel
- mark visit, record time of visit
- send Buffy a visit notification only if - 1) the affinity rating is high and 2) users did not visit each other's pages
With linear programming, the code would look like this:
handleVisit : function(angel, buffy) {
var match_score = getScore(angel, buffy);
var next_match = getNextMatch(angel);
var visit_info = recordVisitAndGetInfo(angel, buffy);
if (match_score > 0.9 && ! visit_info.last_visit) {
sendVisitorEmail(angel, buffy);
}
doSomeFinalThings(match_score, next_match, visit_info);
}
It looks clear, but we need to use asynchronous programming, and the code becomes like this:
handleVisit : function(angel, buffy) {
getScore(angel, buffy, function(match_score) {
getNextMatch(angel, function(next_match) {
recordVisitAndGetInfo(angel, buffy, function(visit_info) {
if (match_score > 0.9 && ! visit_info.last_visit) {
sendVisitorEmail(angel, buffy);
}
doSomeFinalThings(match_score, next_match, visit_info);
});
});
});
}
Now the code is correct, asynchronous, does not contain blocking calls, but reading it has become noticeably more difficult for, for example, a third-party programmer.
Also, we can notice that in our code the calls to the getScore, getNextMatch and recordVisitAndGetInfo functions are independent of each other and could be executed in parallel.
How will TameJS help us?
C TameJS code will look like this:
handleVisit : function(angel, buffy) {
await {
getScore (angel, buffy, defer(var score));
getNextMatch (angel, buffy, defer(var next));
recordVisitAndGetInfo (angel, buffy, defer(var vinfo));
}
if (score > 0.9 && ! vinfo.last_visit) {
sendVisitorEmail(angel, buffy);
}
doSomeFinalThings(score, next, vinfo);
}
The code has become clear, readable, and at the same time it is completely asynchronous and runs faster than the previous asynchronous version due to the parallel execution of getScore, getNextMatch and recordVisitAndGetInfo!
Did you like me as much?
Install TameJS
Installation in Node.JS is done through the npm package manager:
npm install -g tamejs
And then in the code we register the language extension:
require ('tamejs').register (); // register the *.tjs suffix
require ("mylib.tjs"); // then use node.js's import as normal
That's all! Further, Tame itself compiles tjs files into native JS.
How TameJS Works
TameJS syntactic sugar is enclosed in just two, shared, await and defer keywords
var res1, res2;
await {
doOneThing(defer(res1));
andAnother(defer(res2));
}
thenDoSomethingWith(res1, res2);
The await block marks a section of code that contains external events, such as communication with the network or working with the disk, or a timer. The await block contains several defers. The passage of the await block is completed only after all defers in the block have completed. defer () returns an anonymous function to use as a callback for asynchronous calls. If your callback functions assume arguments, specify this set of arguments in defer (). These results will be available upon completion of the await block.
About Authors
TameJS is developed by OkCupid and is distributed under the MIT license. There is a repository on github , the project is young, there is activity in the project.
Project site - tamejs.org
Alternatives
If you are interested in extensions that affect the flow of commands, it is recommended that you also pay attention to StratifiedJS , Step and Seq .