├── .gitignore ├── CONTRIBUTING.md └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | 1. Fork this repository. 2 | 2. Create your branch from "sync" branch. 3 | 3. Modify sources. 4 | 4. Request pull to this repository to same named branch. 5 | 6 | Mainteiner will test your code and updates README.md. 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Asynchronous javascript code with different paradigms 2 | 3 | [Article about that (ru).](https://habrahabr.ru/post/307288/) 4 | 5 | # [Synchronous style](https://github.com/nin-jin/async-js/compare/sync?diff=unified&name=sync) 6 | 7 | * [-] No parallelism. 8 | * [-] Can not be isomorphic in general. 9 | * [-] Expansive stack trace. 10 | * [+] Very easy logic. 11 | * [+] Easy to support. 12 | * [+] Informative stack trace. 13 | * [+] Fast (4ms). 14 | 15 | ``` 16 | TypeError: Cannot read property 'name' of null 17 | at Object.module.exports.getName (./user.js:13:23) 18 | at Object.module.exports.say (./greeter.js:2:41) 19 | at Object. (./index.js:7:13) 20 | at Module._compile (module.js:541:32) 21 | at Object.Module._extensions..js (module.js:550:10) 22 | at Module.load (module.js:456:32) 23 | at tryModuleLoad (module.js:415:12) 24 | at Function.Module._load (module.js:407:3) 25 | at Function.Module.runMain (module.js:575:10) 26 | at startup (node.js:160:18) 27 | ``` 28 | 29 | ## Start 30 | ```sh 31 | npm test 32 | ``` 33 | 34 | ## Logic 35 | 36 | Controller (index.js) gets user info from model (user.js) and calls view (greeter.js) to talk with user. 37 | 38 | # Asynchronous 39 | 40 | ## Logic 41 | 42 | We want to load user info asynchronously. Let's do it with.. 43 | 44 | ## [NodeJS style](https://github.com/nin-jin/async-js/compare/sync...async-nodejs) 45 | 46 | * [-] Non clear logic. 47 | * [-] Too more code. 48 | * [-] Need to rewrite all functions. 49 | * [-] Hard to support. 50 | * [-] Hard parallelism. 51 | * [-] Non informative stack trace. 52 | * [-] Slow (6ms). 53 | * [+] Can be isomorphic. 54 | 55 | ``` 56 | TypeError: Cannot read property 'name' of null 57 | at error (./user.js:31:30) 58 | at fs.readFile.error (./user.js:20:16) 59 | at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:439:3) 60 | ``` 61 | 62 | ## [Promises style](https://github.com/nin-jin/async-js/compare/sync...async-promises) 63 | 64 | * [-] Need to rewrite all functions. 65 | * [-] Hard to support. 66 | * [-] Non informative stack trace. 67 | * [-] Slow (7ms). 68 | * [+] Easy parallelism. 69 | * [+] Can be isomorphic. 70 | 71 | [More info](https://learn.javascript.ru/promise) 72 | 73 | ``` 74 | TypeError: Cannot read property 'name' of null 75 | at getConfig.then.config (./user.js:19:22) 76 | ``` 77 | 78 | ## [Generators&co style](https://github.com/nin-jin/async-js/compare/sync...async-generators-co) 79 | 80 | * [-] Need to rewrite all functions. 81 | * [-] Can not be isomorphic (required [generators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators) support). 82 | * [-] Non informative stack trace. 83 | * [-] Slow (7ms). 84 | * [+] Easy to support. 85 | * [+] Easy parallelism. 86 | 87 | [More info](https://www.npmjs.com/package/co) 88 | 89 | ``` 90 | TypeError: Cannot read property 'name' of null 91 | at Object. (./user.js:18:33) 92 | at next (native) 93 | at onFulfilled (./node_modules/co/index.js:65:19) 94 | ``` 95 | 96 | ## [Async/await transformed to generators by Babel](https://github.com/nin-jin/async-js/compare/sync...async-await-babel) 97 | 98 | * [-] Need to rewrite all functions. 99 | * [-] Can not be isomorphic (required [generators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators) support). 100 | * [-] Expansive stack trace. 101 | * [-] Non informative stack trace. 102 | * [-] Very slow (25ms). 103 | * [+] Easy to support. 104 | * [+] Easy parallelism. 105 | 106 | [More info](https://babeljs.io/docs/plugins/transform-async-to-generator/) 107 | 108 | ``` 109 | TypeError: Cannot read property 'name' of null 110 | at Object. (user.js:18:12) 111 | at undefined.next (native) 112 | at step (C:\proj\async-js\user.js:1:253) 113 | at C:\proj\async-js\user.js:1:430 114 | ``` 115 | 116 | ## [Fibers style](https://github.com/nin-jin/async-js/compare/sync...async-fibers) 117 | 118 | * [-] Can not be isomorphic (NodeJS only). 119 | * [-] Slow (6ms). 120 | * [*] Need to start application in fiber. 121 | * [+] Need not to rewrite all funcitons. 122 | * [+] Easy to support. 123 | * [+] Informative stack trace. 124 | * [+] Easy parallelism. 125 | 126 | [More info](https://github.com/laverdet/node-fibers) 127 | 128 | ``` 129 | TypeError: Cannot read property 'name' of null 130 | at Object.module.exports.getName (./user.js:14:23) 131 | at Object.module.exports.say (./greeter.js:2:41) 132 | at Future.task.error (./index.js:11:17) 133 | at ./node_modules/fibers/future.js:467:21 134 | ``` 135 | 136 | ## [Atoms style](https://github.com/nin-jin/async-js/compare/sync...async-atoms) 137 | 138 | * [-] Need to convert application from control-flow to data-flow. 139 | * [-] Expansive stack trace. 140 | * [-] Very slow (25ms). 141 | * [*] Medium to support. 142 | * [+] Need not to rewrite all funcitons. 143 | * [+] Easy parallelism. 144 | * [+] Can be isomorphic. 145 | * [+] Informative stack trace. 146 | 147 | [More info (russian)](https://habrahabr.ru/post/317360/) 148 | 149 | ``` 150 | TypeError: Cannot read property 'name' of null 151 | at Object.module.exports.getName (./user.js:22:24) 152 | at Object.module.exports.say (./greeter.js:2:41) 153 | at $mol_atom.Atom [as handler] (./index.js:9:13) 154 | at $mol_atom.pull (./node_modules/atom.ts:137:17) 155 | at $mol_atom.actualize (./node_modules/atom.ts:126:23) 156 | at $mol_atom.get (./node_modules/atom.ts:75:9) 157 | at Function.$mol_atom.sync (./node_modules/atom.ts:328:34) 158 | at $mol_defer.run (./node_modules/atom.ts:314:11) 159 | at Function.$mol_defer.run (./defer/defer.ts:53:67) 160 | at Timeout._onTimeout (./defer/defer.ts:28:11) 161 | ``` 162 | 163 | # Comparison 164 | 165 | | Property | Sync | NodeJS | Promises | Generators | Async + Babel | Fibers | Atoms 166 | |--------------------------|----------|----------|----------|------------|---------------|----------|------ 167 | | **Execution time on V8** | **4 ms** | **6 ms** | **7 ms** | **7 ms** | 25 ms | **6 ms** | 25 ms 168 | | **Parallelism** | no | hard | **easy** | **easy** | **easy** | **easy** | **easy** 169 | | **Isomorphism** | some api | **yes** | **yes** | some vm | some vm | no | **yes** 170 | | **Expansive stack** | yes | **no** | **no** | **no** | **no** | **no** | yes 171 | | **Informative stack** | **yes** | no | no | no | no | **yes** | **yes** 172 | | **Complexity of use** | **easy** | hard | hard | **easy** | **easy** | **easy** | **easy** 173 | | **Complexity of debug** | **easy** | hard | hard | hard | hard | **easy** | **easy** 174 | --------------------------------------------------------------------------------