The most seen context of Jscex is “JavaScript Asynchronous Programming”, and it can be used on both the browser and the server. Recently, Node.js is very popular, and the original Windows version has just been released, and many students are using it to make websites and something like that. The most famous framework used by Node.js based websites is Express, which is easy to use.
JavaScript is a kind of language with no blocking characteristics, so all kinds of APIs are designed to be asynchronous, which is good to both the scalability of the server and the response ability of a client page. But there will be some problems when programming. For example, it is a ToDo demonstration of a simple handler, because the data base needs to be checked, so there should be callbacks:
1. exports.index = function (req, res, next) {
2. db.query
(‘select * from todo order by finished asc, id asc limit 50′, function
(err, rows) {
3. if (err) return next(err);
4. res.render(‘index’, { todos: rows });
5. });
6. };
The db variable is used to operate the MySQL data base. Its query method introduces SQLs (maybe some indexes) and provides a callback function to suggest errors or return to the search results. In the callback, we must be clear that whether there is an error. If there is, we have to use the “next” framework to report “error”. We should do this in every asynchronous operation step. If there is another check after this check, we must do another error checking. Every handler requires this, it is also something annoying about asynchronous programming: it is hard to do an overall exception handling, and the handlers should be placed everywhere. It will turn something abnormal, which will be hard to find out.
I used the Jscex to modifify the ToDo website. At first, I enable the inquiry of MySQL to access.
Jscex(lib\jscex.mysql.js):
1. exports.jscexify = function (db) {
2. db.queryAsync = function () {
3. var _this = this;
4.
5. var args = [];
6. for (var i = 0; i < arguments.length; i++) {
7. args.push(arguments[i]);
8. }
9.
10. var delegate = {
11. onStart: function (callback) {
12.
13. args.push(function (err, result) {
14. if (err) {
15. callback("failure", err);
16. } else {
17. callback("success", result);
18. }
19. });
20.
21. _this.query.apply(_this, args);
22. }
23. };
24.
25. return new Jscex.Async.Task(delegate);
26. }
27. }
Generally speaking, not so many codes are required to modify an asynchronous interface with Jscex (what is the most important is just the onStart function). There are nearly 30 lines of codes, but most of them are there to support the elongated indexes, so the query Async function will retain all the indexes being called, and complete it with a callback, then call the query function itself. Now, you can change the indexed and other handlers (controller\todo.js), for example:
1. exports.index = toHandler(eval(Jscex.compile("async", function (req, res) {
2.
3. var todos = $await(db.queryAsync(‘select * from todo order by finished asc, id asc limit 50′));
4. res.render("index", { todos: todos });
5.
6. })));
The toHandler function is a handler turning a “receiving req and res, and returning to Task” function to a standard “receiving req, res and next” handlers, dealing with errors al-together.
1. var toHandler = function (asyncFunc) {
2. return function (req, res, next) {
3. var task = asyncFunc(req, res);
4. task.addListener(function () {
5. if (task.status == "failed") {
6. next(task.error);
7. }
8. });
9. task.start();
10. }
11. }
ToDo websites are based on Express, ejs and MySQL, and I add Jscex as its sub-module. If you are going to put some ToDo codes in it, you can:
1. > git clone git://github.com/JeffreyZhao/todo.git
2. > cd todo
3. > git submodule init
4. > git submodule update
5. > npm install express ejs mysql
6. > node server.js
You may still be confused at the present. But after acquiring some basic knowledge about Jscex and reading my article, you will find that it is really a non-traditional way.


