1 | # Continuation.js
|
2 |
|
3 | Continuation.js is a compiler for asynchronous [Continuation-Passing Style](http://en.wikipedia.org/wiki/Continuation-passing_style) transformation, which simplifies asynchronous JavaScript programming.
|
4 |
|
5 | Typically, writing with asynchronous control flow is a pain because you will easily write nested callbacks like below:
|
6 |
|
7 | ```javascript
|
8 | function textProcessing(callback) {
|
9 | fs.readFile('somefile.txt', 'utf-8', function (err, contents) {
|
10 | if (err) return callback(err);
|
11 | //process contents
|
12 | contents = contents.toUpperCase();
|
13 | fs.readFile('somefile2.txt', 'utf-8', function (err, contents2) {
|
14 | if (err) return callback(err);
|
15 | contents += contents2;
|
16 | fs.writeFile('somefile_concat_uppercase.txt', contents, function (err) {
|
17 | if (err) return callback(err);
|
18 | callback(null, contents);
|
19 | });
|
20 | });
|
21 | });
|
22 | }
|
23 | textProcessing(function (err, contents) {
|
24 | if (err)
|
25 | console.error(err);
|
26 | });
|
27 | ```
|
28 |
|
29 | This kind of coding style is called 'callback hells' or 'callback pyramids'. While using Continuation.js, you directly write:
|
30 |
|
31 | ```javascript
|
32 | function textProcessing(ret) {
|
33 | fs.readFile('somefile.txt', 'utf-8', cont(err, contents));
|
34 | if (err) return ret(err);
|
35 | contents = contents.toUpperCase();
|
36 | fs.readFile('somefile2.txt', 'utf-8', cont(err, contents2));
|
37 | if (err) return ret(err);
|
38 | contents += contents2;
|
39 | fs.writeFile('somefile_concat_uppercase.txt', contents, cont(err));
|
40 | if (err) return ret(err);
|
41 | ret(null, contents);
|
42 | }
|
43 | textProcessing(cont(err, contents));
|
44 | if (err)
|
45 | console.error(err);
|
46 | ```
|
47 |
|
48 | Or even simpler:
|
49 |
|
50 | ```javascript
|
51 | function textProcessing(ret) {
|
52 | fs.readFile('somefile.txt', 'utf-8', obtain(contents));
|
53 | contents = contents.toUpperCase();
|
54 | fs.readFile('somefile2.txt', 'utf-8', obtain(contents2));
|
55 | contents += contents2;
|
56 | fs.writeFile('somefile_concat_uppercase.txt', contents, obtain());
|
57 | ret(null, contents);
|
58 | }
|
59 | try {
|
60 | textProcessing(obtain(contents));
|
61 | } catch(err) {
|
62 | console.error(err);
|
63 | }
|
64 | ```
|
65 |
|
66 | ## Features
|
67 |
|
68 | * A JIT (Just-in-time compilation) and AOT (Ahead-of-time) compiler
|
69 | * No runtime dependences
|
70 | * No additional non-native JavaScript syntax
|
71 | * Flexible coding style
|
72 | * Readable and debuggable compiled code
|
73 | * Compatible with [CoffeeScript](http://coffeescript.org/) and [LiveScript](http://livescript.net/)
|
74 | * Supports both Node.js and browser-side JavaScript
|
75 | * Parallel execution supported
|
76 |
|
77 | ## Installation
|
78 |
|
79 | Install Continuation.js with [NPM](https://npmjs.org/package/continuation):
|
80 |
|
81 | npm install -g continuation
|
82 |
|
83 | ## Usage
|
84 |
|
85 | Usage: continuation [options] <file.js/file.coffee> [arguments]
|
86 |
|
87 | Options:
|
88 |
|
89 | -h, --help output usage information
|
90 | -V, --version output the version number
|
91 | -p, --print compile script file and print it
|
92 | -o, --output <filename> compile script file and save as <filename>
|
93 | -e, --explicit compile only if "use continuation" is explicitly declared
|
94 | -c, --cache [directory] run and cache compiled sources to [directory], by default [directory] is /tmp/continuation
|
95 | -v, --verbose print verbosal information to stderr
|
96 |
|
97 | ## Documentation
|
98 |
|
99 | Continuation.js is still under development. Most functionalities are not fully implemented or tested.
|
100 |
|
101 | More details are to be written.
|
102 |
|
103 | ## Examples
|
104 |
|
105 | Calcuating Fibonacci sequence and printing one number by every one second:
|
106 |
|
107 | ```javascript
|
108 | var fib = function () {
|
109 | var a = 0, current = 1;
|
110 | while (true) {
|
111 | var b = a;
|
112 | a = current;
|
113 | current = a + b;
|
114 | setTimeout(cont(), 1000);
|
115 | console.log(current);
|
116 | }
|
117 | };
|
118 | fib();
|
119 | ```
|
120 |
|
121 | Read 5 files in sequence:
|
122 |
|
123 | ```javascript
|
124 | var fs = require('fs');
|
125 |
|
126 | for (var i = 0; i < 4; i++) {
|
127 | fs.readFile('text' + i + '.js', 'utf-8', obtain(text));
|
128 | console.log(text);
|
129 | }
|
130 |
|
131 | console.log('Done');
|
132 | ```
|
133 |
|
134 | More examples are available in 'examples' directory and 'test' directory.
|