├── chapter2 ├── 2.3 fs │ ├── foo.txt │ ├── dir1 │ │ ├── file1.txt │ │ └── dir2 │ │ │ └── file2.txt │ ├── readFileSync.js │ ├── writeFile.js │ ├── stat.js │ └── listFile.js ├── 2.9 event │ ├── test0.txt │ ├── test1.txt │ ├── test2.txt │ ├── test3.txt │ ├── exp1.js │ ├── exp4.js │ ├── exp3.js │ └── exp2.js ├── 2.4 http │ ├── test.txt │ ├── simpleServer.js │ ├── upload │ │ ├── upload.html │ │ └── upload.js │ ├── login.html │ ├── http-client.js │ ├── proxy.js │ └── static-serve.js ├── 2.8 stream │ ├── test.txt │ ├── readline │ │ ├── foo.txt │ │ └── readline.js │ ├── exp2.js │ ├── exp1.js │ └── inherit.js ├── eventLoop │ ├── foo.txt │ ├── exp1.js │ ├── test.html │ └── exp2.js ├── 2.2 buffer │ ├── test.txt │ ├── exp1.js │ ├── exp2.js │ └── highwatermark.js ├── 2.1 module │ ├── require │ │ ├── test.js │ │ └── module.js │ ├── require.js │ └── person.js ├── 2.10 cluster │ ├── child_process │ │ ├── example │ │ ├── sendObj │ │ │ ├── worker.js │ │ │ └── master.js │ │ ├── worker.js │ │ ├── execFile.js │ │ ├── child_process.js │ │ └── spawn.js │ └── exp2.js ├── 2.6 ssl │ ├── client2.js │ ├── server.js │ ├── client.js │ ├── client-csr.pem │ ├── server-csr.pem │ ├── client-cert.pem │ ├── server-cert.pem │ ├── server.pem │ └── client.pem ├── 2.12 timer │ ├── setTimeout&setImmediate.js │ └── immediate.js ├── error │ └── exp1.js ├── 2.11 process │ ├── errorHandling.js │ ├── environment-variable.js │ └── myTimeZone.js ├── 2.5 tcp │ └── exp1.js └── util │ └── exp1.js ├── chapter3 ├── async │ ├── 2.txt │ ├── 3.txt │ ├── 4.txt │ ├── foo.txt │ ├── exp2.js │ ├── error.js │ ├── exp1.js │ ├── async.js │ └── promise.js ├── generator │ ├── bar.txt │ ├── foo.txt │ ├── exp2.js │ ├── exp3.js │ ├── exp.js │ ├── throw.js │ ├── auto_execute.js │ ├── return.js │ └── co.js ├── 3.3 array │ ├── keys.js │ ├── fill.js │ └── from.js ├── 3.4 Func │ ├── default param.js │ ├── anonymous.js │ ├── exp1.js │ └── this.js ├── 3.11 babel │ ├── .babelrc │ ├── exp1.js │ ├── test.js │ └── package.json ├── 3.2 let & const │ ├── const.js │ └── let.js ├── 3.5 Set&Map │ ├── weakset.js │ ├── exp1.js │ ├── exp2.js │ └── map.js ├── 3.8 Class │ ├── ES5_Class.js │ ├── __proto__.js │ ├── static.js │ ├── ES6_Class.js │ ├── ES5_Inherit.js │ └── ES6_inherit.js ├── proxy │ └── proxy.js ├── 3.6 iterator │ ├── exp1.js │ ├── exp2.js │ └── myIter.js └── 3.7 Object │ ├── setProto.js │ ├── exp1.js │ └── iter.js ├── .gitignore ├── chapter4 ├── 4.3 Promise │ ├── 2.txt │ ├── 3.txt │ ├── 4.txt │ ├── 1.txt │ ├── bar.txt │ ├── baz.txt │ ├── foo.txt │ ├── bluebird.js │ ├── thenable.js │ ├── readFile_promise.js │ ├── async-read.js │ ├── async.js │ ├── error.js │ └── promise.js ├── 4.5 async&awiat │ ├── 1.txt │ ├── 2.txt │ ├── 3.txt │ ├── 4.txt │ └── exp.js ├── 4.2 Callback&Cps&Async │ ├── async │ │ ├── 1.txt │ │ ├── 2.txt │ │ ├── 3.txt │ │ ├── exp1.js │ │ ├── map.js │ │ ├── series.js │ │ ├── parallel.js │ │ └── waterfall.js │ ├── Q │ │ ├── q1.js │ │ └── q.js │ ├── exp.js │ └── cps-callback.js └── 4.4 Generator │ ├── exp4.js │ ├── exp3.js │ ├── iteratorTest.js │ ├── exp5.js │ ├── exp2.js │ ├── auto_exec_V2.js │ ├── resolve2.js │ ├── auto_exec_V1.js │ ├── async.js │ └── co.js ├── appendix ├── redis │ ├── pub-sub │ │ ├── txt1.txt │ │ ├── txt2.txt │ │ ├── txt3.txt │ │ ├── exp3.js │ │ └── exp2.js │ ├── prod-consum │ │ └── pro.js │ ├── exp1.js │ └── redis-promise.js └── Loa │ ├── context.js │ ├── test │ └── example.js │ ├── application.js │ └── LICENSE ├── chapter5 ├── readme.md └── return next.js ├── chapter6 └── readme.md ├── package.json ├── chapter7 └── jasmine │ ├── spec │ ├── support │ │ └── jasmine.json │ ├── async.js │ ├── spy.js │ ├── exp1.js │ └── exp2.js │ └── src │ └── exp1.js └── chapter8 ├── assert └── exp1.js ├── domainFirstTry ├── test.js └── domain.js ├── try.js └── cluster.js /chapter2/2.3 fs/foo.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /chapter3/async/2.txt: -------------------------------------------------------------------------------- 1 | Node -------------------------------------------------------------------------------- /chapter3/async/3.txt: -------------------------------------------------------------------------------- 1 | from -------------------------------------------------------------------------------- /chapter3/async/4.txt: -------------------------------------------------------------------------------- 1 | here -------------------------------------------------------------------------------- /chapter3/async/foo.txt: -------------------------------------------------------------------------------- 1 | Hello -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .idea -------------------------------------------------------------------------------- /chapter2/2.3 fs/dir1/file1.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /chapter2/2.9 event/test0.txt: -------------------------------------------------------------------------------- 1 | test0 -------------------------------------------------------------------------------- /chapter2/2.9 event/test1.txt: -------------------------------------------------------------------------------- 1 | test1 -------------------------------------------------------------------------------- /chapter2/2.9 event/test2.txt: -------------------------------------------------------------------------------- 1 | test2 -------------------------------------------------------------------------------- /chapter2/2.9 event/test3.txt: -------------------------------------------------------------------------------- 1 | test3 -------------------------------------------------------------------------------- /chapter3/generator/bar.txt: -------------------------------------------------------------------------------- 1 | bar -------------------------------------------------------------------------------- /chapter3/generator/foo.txt: -------------------------------------------------------------------------------- 1 | foo -------------------------------------------------------------------------------- /chapter4/4.3 Promise/2.txt: -------------------------------------------------------------------------------- 1 | 2.txt -------------------------------------------------------------------------------- /chapter4/4.3 Promise/3.txt: -------------------------------------------------------------------------------- 1 | 3.txt -------------------------------------------------------------------------------- /chapter4/4.3 Promise/4.txt: -------------------------------------------------------------------------------- 1 | 4.txt -------------------------------------------------------------------------------- /appendix/redis/pub-sub/txt1.txt: -------------------------------------------------------------------------------- 1 | txt1 -------------------------------------------------------------------------------- /appendix/redis/pub-sub/txt2.txt: -------------------------------------------------------------------------------- 1 | txt2 -------------------------------------------------------------------------------- /appendix/redis/pub-sub/txt3.txt: -------------------------------------------------------------------------------- 1 | txt3 -------------------------------------------------------------------------------- /chapter2/2.3 fs/dir1/dir2/file2.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /chapter2/2.4 http/test.txt: -------------------------------------------------------------------------------- 1 | Hello Node -------------------------------------------------------------------------------- /chapter2/2.8 stream/test.txt: -------------------------------------------------------------------------------- 1 | Hello Node -------------------------------------------------------------------------------- /chapter2/eventLoop/foo.txt: -------------------------------------------------------------------------------- 1 | I am foo.txt -------------------------------------------------------------------------------- /chapter4/4.3 Promise/1.txt: -------------------------------------------------------------------------------- 1 | Hello World -------------------------------------------------------------------------------- /chapter4/4.3 Promise/bar.txt: -------------------------------------------------------------------------------- 1 | I am bar.txt -------------------------------------------------------------------------------- /chapter4/4.3 Promise/baz.txt: -------------------------------------------------------------------------------- 1 | I am baz.txt -------------------------------------------------------------------------------- /chapter4/4.3 Promise/foo.txt: -------------------------------------------------------------------------------- 1 | I am foo.txt -------------------------------------------------------------------------------- /chapter4/4.5 async&awiat/1.txt: -------------------------------------------------------------------------------- 1 | I am 1.txt -------------------------------------------------------------------------------- /chapter4/4.5 async&awiat/2.txt: -------------------------------------------------------------------------------- 1 | I am 2.txt -------------------------------------------------------------------------------- /chapter4/4.5 async&awiat/3.txt: -------------------------------------------------------------------------------- 1 | I am 3.txt -------------------------------------------------------------------------------- /chapter4/4.5 async&awiat/4.txt: -------------------------------------------------------------------------------- 1 | I am 4.txt -------------------------------------------------------------------------------- /chapter4/4.2 Callback&Cps&Async/async/1.txt: -------------------------------------------------------------------------------- 1 | 1.txt -------------------------------------------------------------------------------- /chapter4/4.2 Callback&Cps&Async/async/2.txt: -------------------------------------------------------------------------------- 1 | 2.txt -------------------------------------------------------------------------------- /chapter4/4.2 Callback&Cps&Async/async/3.txt: -------------------------------------------------------------------------------- 1 | 3.txt -------------------------------------------------------------------------------- /chapter2/2.2 buffer/test.txt: -------------------------------------------------------------------------------- 1 | 八百标兵奔北坡,北坡炮兵并排跑,炮兵怕把标兵碰,标兵怕碰炮兵炮。 2 | -------------------------------------------------------------------------------- /chapter2/2.8 stream/readline/foo.txt: -------------------------------------------------------------------------------- 1 | line1 2 | line2 3 | line3 4 | line4 -------------------------------------------------------------------------------- /chapter3/3.3 array/keys.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/7/11. 3 | */ 4 | -------------------------------------------------------------------------------- /chapter3/3.4 Func/default param.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/7/10. 3 | */ 4 | -------------------------------------------------------------------------------- /chapter4/4.3 Promise/bluebird.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/5/23. 3 | */ 4 | -------------------------------------------------------------------------------- /chapter5/readme.md: -------------------------------------------------------------------------------- 1 | For chapter5 ,please go to KoaBlog(https://github.com/Yuki-Minakami/KoaBlog) -------------------------------------------------------------------------------- /chapter6/readme.md: -------------------------------------------------------------------------------- 1 | For chapter6, please go to PHelper(https://github.com/Yuki-Minakami/PHelper) -------------------------------------------------------------------------------- /chapter2/2.1 module/require/test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/5/26. 3 | */ 4 | var test = require("./module.js"); 5 | -------------------------------------------------------------------------------- /chapter3/3.11 babel/.babelrc: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "presets": [ 4 | "es2015" 5 | ], 6 | "plugins": ["es6-promise"] 7 | } -------------------------------------------------------------------------------- /chapter2/2.10 cluster/child_process/example: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yuki-Minakami/BookExample/HEAD/chapter2/2.10 cluster/child_process/example -------------------------------------------------------------------------------- /chapter2/2.1 module/require.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/1/19. 3 | */ 4 | var person = require("./person"); 5 | console.log(require.cache); 6 | 7 | -------------------------------------------------------------------------------- /chapter2/2.1 module/require/module.js: -------------------------------------------------------------------------------- 1 | function moduleTest(){ 2 | 3 | setInterval(function(){ 4 | console.log("test"); 5 | },1000) 6 | } 7 | 8 | moduleTest(); 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "BookExample", 3 | "version": "0.0.1", 4 | "dependencies": { 5 | "formidable": "", 6 | "q":"", 7 | "redis":"" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /chapter2/2.6 ssl/client2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/5/6. 3 | */ 4 | var https = require("https"); 5 | 6 | https.get("https://localhost:3001",function(res){ 7 | console.log(res); 8 | }) -------------------------------------------------------------------------------- /chapter4/4.3 Promise/thenable.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/8/6. 3 | */ 4 | var obj = { 5 | then :function(){ 6 | console.log("I am a method"); 7 | } 8 | } 9 | Promise.resolve(obj); -------------------------------------------------------------------------------- /chapter2/2.3 fs/readFileSync.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/2/18. 3 | */ 4 | var fs= require("fs"); 5 | var data = fs.readFileSync("foo.txt",{encoding:"UTF-8"}); 6 | console.log(data); 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /chapter3/3.2 let & const/const.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/3/13. 3 | */ 4 | const a =1; 5 | //a = 2; // TypeError: Assignment to constant variable. 6 | const b = {}; 7 | b.name ="lear"; 8 | b.age =10; 9 | console.log(b);//{ name: 'lear', age: 10 } -------------------------------------------------------------------------------- /chapter3/async/exp2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/8/2. 3 | */ 4 | async function test(){ 5 | var data = await new Promise(function(resolve,reject){ 6 | resolve("hah"); 7 | }); 8 | console.log(data); 9 | } 10 | 11 | test(); -------------------------------------------------------------------------------- /chapter7/jasmine/spec/support/jasmine.json: -------------------------------------------------------------------------------- 1 | { 2 | "spec_dir": "spec", 3 | "spec_files": [ 4 | "async.js" 5 | ], 6 | "helpers": [ 7 | "helpers/**/*.js" 8 | ], 9 | "stopSpecOnExpectationFailure": false, 10 | "random": false 11 | } 12 | -------------------------------------------------------------------------------- /chapter3/3.11 babel/exp1.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | function timeout(ms) { 5 | return new Promise((resolve, reject) => { 6 | setTimeout(resolve, ms, 'done'); 7 | }); 8 | } 9 | 10 | timeout(1000).then((value) => { 11 | console.log(value); 12 | }); -------------------------------------------------------------------------------- /chapter3/3.4 Func/anonymous.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/1/20. 3 | */ 4 | var func1 = a => a; 5 | //等价于 6 | var func1 = function(a){ 7 | return a; 8 | } 9 | 10 | var func2 = (arg1="Hello",arg2="Node")=> console.log(arg1,arg2); 11 | 12 | func2(); -------------------------------------------------------------------------------- /chapter4/4.4 Generator/exp4.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/2/24. 3 | */ 4 | function* Generator() { 5 | yield "Hello Node"; 6 | yield "From Lear" 7 | yield "end" 8 | } 9 | var gen = Generator(); 10 | for(let i of gen){ 11 | console.log(i); 12 | } -------------------------------------------------------------------------------- /chapter2/2.10 cluster/child_process/sendObj/worker.js: -------------------------------------------------------------------------------- 1 | process.on('message', (m, server) => { 2 | if (m === 'server') { 3 | server.on('connection', (socket) => { 4 | socket.end('handled by child'); 5 | }); 6 | } 7 | }); 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /chapter2/2.2 buffer/exp1.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/3/5. 3 | */ 4 | var buffer= Buffer.from([0x48,0x65,0x6c,0x6c,0x6f,0x20,0x4e,0x6f,0x64 ,0x65]);//"Hello Node" 5 | var buffer = Buffer.from("Hello Node"); 6 | console.log(buffer);// 7 | -------------------------------------------------------------------------------- /chapter2/2.9 event/exp1.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/2/19. 3 | */ 4 | var eventEmitter = require("events"); 5 | var myEmitter = new eventEmitter(); 6 | myEmitter.on("event",function(){ 7 | console.log("event"); 8 | }) 9 | myEmitter.emit("event"); 10 | 11 | 12 | -------------------------------------------------------------------------------- /chapter2/2.12 timer/setTimeout&setImmediate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/5/2. 3 | */ 4 | setTimeout(function timeout (args) { 5 | console.log(args); 6 | },0,'timeout'); 7 | 8 | setImmediate(function immediate () { 9 | console.log('immediate'); 10 | }); 11 | 12 | -------------------------------------------------------------------------------- /chapter2/error/exp1.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/3/4. 3 | */ 4 | var fs = require("fs") 5 | //fs.readFile("some file",function(err,data){ 6 | // if(err){ 7 | // throw err; 8 | // } 9 | //}) 10 | 11 | const err = new Error('The message'); 12 | console.log(err.message); -------------------------------------------------------------------------------- /chapter3/3.5 Set&Map/weakset.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/6/20. 3 | */ 4 | var wset = new WeakSet(); 5 | 6 | wset.add({a:1,b:2});//success 7 | //wset.add(1);//TypeError: Invalid value used in weak set 8 | console.log(wset.size) 9 | 10 | 11 | var array = [1,2,3,4,5] 12 | 13 | 14 | -------------------------------------------------------------------------------- /chapter4/4.2 Callback&Cps&Async/async/exp1.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/5/19. 3 | */ 4 | var func1 = function(){ 5 | require("fs").readFile("1.txt",(err,data) =>{ 6 | // console.log(data); 7 | return data; 8 | }) 9 | } 10 | 11 | console.log(func1()); 12 | 13 | 14 | -------------------------------------------------------------------------------- /chapter4/4.4 Generator/exp3.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/2/22. 3 | */ 4 | function* foo(x){ 5 | var y = yield(x+1) 6 | y=10; 7 | return y; 8 | } 9 | var gen = foo(5); 10 | console.log(gen.next());//{ value: 6, done: false } 11 | console.log(gen.next());//{ value: 10, done: true } -------------------------------------------------------------------------------- /chapter3/async/error.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/5/22. 3 | */ 4 | var myReadFile = require("./promise"); 5 | 6 | async function func(path){ 7 | try{ 8 | await myReadFile(path); 9 | }catch(e){ 10 | console.log(e); 11 | } 12 | 13 | } 14 | 15 | func(); 16 | 17 | 18 | -------------------------------------------------------------------------------- /chapter4/4.2 Callback&Cps&Async/Q/q1.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/2/20. 3 | */ 4 | var Q = require("q"); 5 | var fs= require("fs"); 6 | var fs_readfile=Q.nfcall(fs.readFile,'../test1.txt','utf-8'); 7 | 8 | fs_readfile.then(callback); 9 | 10 | function callback(data){ 11 | console.log(data) 12 | } -------------------------------------------------------------------------------- /chapter7/jasmine/src/exp1.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/3/11. 3 | */ 4 | var http = require("http"); 5 | var foo = { 6 | getRequest:function(url){ 7 | http.get(url, function (data) { 8 | console.log(data.statusCode); 9 | }) 10 | } 11 | } 12 | 13 | module.exports = foo; -------------------------------------------------------------------------------- /chapter3/3.11 babel/test.js: -------------------------------------------------------------------------------- 1 | //'use strict'; 2 | 3 | //require('babel-polyfill'); 4 | 5 | function timeout(ms) { 6 | return new Promise(function (resolve, reject) { 7 | setTimeout(resolve, ms, 'done'); 8 | }); 9 | } 10 | 11 | timeout(1000).then(function (value) { 12 | console.log(value); 13 | }); -------------------------------------------------------------------------------- /chapter3/3.8 Class/ES5_Class.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/1/22. 3 | */ 4 | function Person(name,age){ 5 | this.name = name; 6 | this.age = age; 7 | } 8 | Person.prototype.getInfo = function(){ 9 | return this.name +","+this.age; 10 | } 11 | 12 | module.exports = Person; 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /chapter2/eventLoop/exp1.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/4/30. 3 | */ 4 | var fs = require("fs"); 5 | 6 | fs.readFile("foo.txt",function(err,data){ 7 | console.log(data); 8 | while(true){}//死循环阻塞了事件循环,后面所有的代码都不会执行 9 | }); 10 | 11 | setTimeout(function(){ 12 | console.log("done"); 13 | },1000); 14 | 15 | -------------------------------------------------------------------------------- /chapter2/2.10 cluster/child_process/worker.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/1/19. 3 | */ 4 | 5 | var begin = process.argv[2]; 6 | console.log("I am worker "+begin); 7 | process.on("message",function(msg){ 8 | console.log("from parent ",msg); 9 | process.exit(); 10 | }); 11 | process.send({hello:"parent"}); 12 | 13 | -------------------------------------------------------------------------------- /chapter2/2.3 fs/writeFile.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likaiboy on 2017/9/24. 3 | */ 4 | var fs = require("fs"); 5 | fs.writeFile("foo.txt","你好",{flag:"a",encoding:"UTF-8"}, function(err){ 6 | if(err){ 7 | console.log(err); 8 | return; 9 | } 10 | console.log("success"); 11 | }); 12 | -------------------------------------------------------------------------------- /chapter3/async/exp1.js: -------------------------------------------------------------------------------- 1 | var fs= require("fs"); 2 | fs.readFile("1.txt",function(err,data){ 3 | fs.readFile("2.txt",function(err,data2){ 4 | console.log(data.toString(),data2.toString()); 5 | }) 6 | }); 7 | 8 | fs.readFile("1.txt",(err,data)=>(fs.readFile("2.txt",(err,data2)=>(console.log(data.toString(),data2.toString()))))); -------------------------------------------------------------------------------- /chapter3/generator/exp2.js: -------------------------------------------------------------------------------- 1 | 2 | function* Generator() { 3 | yield "Hello Node"; 4 | yield "From Lear" 5 | return "end" 6 | } 7 | var gen = Generator(); 8 | for(let i of gen){ 9 | console.log(i); 10 | //输出结果 11 | // Hello Node 12 | //From Lear 13 | } 14 | 15 | // //和for/of循环等价 16 | // Array.from(Generator()) -------------------------------------------------------------------------------- /chapter3/3.11 babel/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "application-name", 3 | "version": "0.0.1", 4 | "devDependencies": { 5 | "babel-polyfill": "^6.23.0", 6 | "babel-preset-es2015": "^6.24.1", 7 | "babel-preset-stage-2": "^6.24.1" 8 | }, 9 | "dependencies": { 10 | "babel-plugin-es6-promise": "^1.1.1" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /chapter3/proxy/proxy.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/2/14. 3 | */ 4 | var proxy = new Proxy(Buffer,{ 5 | getStr:function(target, property){ 6 | return "str"; 7 | } 8 | }); 9 | 10 | var obj = Object.create(proxy); 11 | obj.getStr() 12 | 13 | 14 | var str = new Buffer("test") 15 | 16 | 17 | console.log(str.toString()); -------------------------------------------------------------------------------- /chapter3/3.5 Set&Map/exp1.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/3/14. 3 | */ 4 | var set = new Set([1,2,3,4,4,5]);//使用构造函数初始化一个set 5 | console.log(set);//Set { 1, 2, 3, 4, 5 } 6 | set.add(6);//向set添加一个值 7 | set.delete(5);//从set删除一个值 8 | set.has(6);//true 9 | for(var i of set){ 10 | console.log(i);//1 2 3 4 6 11 | } 12 | set.clear();//清除所有元素 -------------------------------------------------------------------------------- /chapter3/generator/exp3.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/4/10. 3 | */ 4 | /** 5 | * Created by likai on 2017/4/10. 6 | */ 7 | function* generator() { 8 | 9 | yield console.log(a);//a is not defined 10 | return "end"; 11 | }; 12 | var gen = generator(); 13 | 14 | try{ 15 | gen.next(); 16 | }catch(e){ 17 | 18 | } 19 | 20 | -------------------------------------------------------------------------------- /appendix/redis/prod-consum/pro.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/2/16. 3 | */ 4 | var redis = require("redis"); 5 | var client = redis.createClient('6379', '127.0.0.1'); 6 | client.on("error", function(error) { 7 | console.log(error); 8 | }); 9 | 10 | 11 | var key = "demo:mq:test"; 12 | var msg = "hello world"; 13 | client.lpush(key, msg); -------------------------------------------------------------------------------- /chapter3/3.5 Set&Map/exp2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/3/14. 3 | */ 4 | let set = new Set([1, 2, 3]); 5 | 6 | for (let i of set.keys()) { 7 | console.log(i);// 1 2 3 8 | } 9 | for (let i of set.values()) { 10 | console.log(i); // 1 2 3 11 | } 12 | for (let i of set.entries()) { 13 | console.log(i); //[1,1] [2,2] [3,3] 14 | } 15 | -------------------------------------------------------------------------------- /chapter4/4.4 Generator/iteratorTest.js: -------------------------------------------------------------------------------- 1 | var Iter ={ 2 | 3 | [Symbol.iterator] : function () { 4 | var i=0; 5 | return { 6 | next: function () { 7 | return ++i; 8 | } 9 | }; 10 | } 11 | }; 12 | 13 | var obj = new Iter[Symbol.iterator](); 14 | obj.next();//1 15 | obj.next();//2 16 | -------------------------------------------------------------------------------- /chapter2/2.12 timer/immediate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/5/2. 3 | */ 4 | 5 | setImmediate(function(arg) { 6 | console.log('executing immediate:', arg); 7 | }, 'so immediate'); 8 | 9 | setTimeout(function(){ 10 | console.log("timeout"); 11 | },0); 12 | 13 | process.nextTick(function(){ 14 | console.log("next Tick"); 15 | }); 16 | -------------------------------------------------------------------------------- /chapter4/4.4 Generator/exp5.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/5/9. 3 | */ 4 | function * Generator(){ 5 | var result = yield Promise.resolve("Hello Node") 6 | console.log(result); 7 | } 8 | 9 | var gen = Generator() 10 | var result = gen.next(); 11 | result.value.then(function(data){ 12 | gen.next(data) 13 | }); 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /chapter2/2.1 module/person.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/1/19. 3 | */ 4 | var Person = { 5 | listen:function(){ 6 | console.log("I am listening"); 7 | }, 8 | talk:function(){ 9 | console.log("I am talking"); 10 | } 11 | //....... 12 | } 13 | 14 | 15 | 16 | module.exports = Person; 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /chapter3/generator/exp.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/4/10. 3 | */ 4 | function *gen(x){ 5 | var y = 0; 6 | yield y = x+1; 7 | return "end"; 8 | } 9 | 10 | var gen = gen(5); 11 | //console.log(gen.next()); 12 | //console.log(gen.next()); 13 | //console.log(gen.next()); 14 | console.log(gen[Symbol.iterator]);//输出[Function: [Symbol.iterator]] -------------------------------------------------------------------------------- /chapter4/4.2 Callback&Cps&Async/exp.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/2/19. 3 | */ 4 | var fs = require("fs"); 5 | function read(path){ 6 | fs.readFile(path,{encoding:"utf-8"},function(err,data){ 7 | console.log(data); 8 | }) 9 | } 10 | read("../test1.txt"); 11 | read("../test2.txt"); 12 | read("../test3.txt"); 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /chapter2/eventLoop/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 | 9 | 10 | 19 | -------------------------------------------------------------------------------- /chapter4/4.2 Callback&Cps&Async/async/map.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/5/24. 3 | */ 4 | var async = require("async"); 5 | var fs= require("fs"); 6 | 7 | function myReadFile(path,callback){ 8 | fs.readFile(path,"utf-8",callback); 9 | } 10 | 11 | async.map(['1.txt','2.txt','3.txt'], myReadFile, function(err, results) { 12 | console.log(results); 13 | }); -------------------------------------------------------------------------------- /chapter8/assert/exp1.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/3/5. 3 | */ 4 | const assert = require('assert'); 5 | 6 | assert.equal(1, 1); 7 | // OK, 1 == 1 8 | assert.equal(1, '1'); 9 | // OK, 1 == '1' 10 | 11 | //assert.equal(1, 2); 12 | // AssertionError: 1 == 2 13 | assert.throws( 14 | () => { 15 | throw new Error('Wrong value'); 16 | }, 17 | Error 18 | ); -------------------------------------------------------------------------------- /chapter2/2.10 cluster/child_process/sendObj/master.js: -------------------------------------------------------------------------------- 1 | const child = require('child_process').fork('worker.js'); 2 | 3 | // Open up the server object and send the handle. 4 | const server = require('net').createServer(); 5 | server.on('connection', (socket) => { 6 | socket.end('handled by parent'); 7 | }); 8 | server.listen(1337, () => { 9 | child.send('server', server); 10 | }); -------------------------------------------------------------------------------- /chapter2/2.10 cluster/child_process/execFile.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/5/4. 3 | */ 4 | const exec = require('child_process').exec; 5 | 6 | //example是使用C语言编写的一个hello world程序,在mac平台下使用GCC编译,在windows上运行下面的代码可能会出现错误 7 | const child = exec('example', (error, stdout, stderr) => { 8 | if (error) { 9 | throw error; 10 | } 11 | console.log(stdout); 12 | }); 13 | 14 | -------------------------------------------------------------------------------- /chapter4/4.4 Generator/exp2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/2/22. 3 | */ 4 | function* foo(x) { 5 | var y = 2 * (yield (x + 1)); 6 | console.log(y); 7 | var z = yield (y / 3); 8 | return (x + y + z); 9 | } 10 | 11 | var a = foo(5); 12 | console.log(a.next()); // Object{value:6, done:false} 13 | console.log(a.next(8)); // Object{value:NaN, done:false} 14 | console.log(a.next()); -------------------------------------------------------------------------------- /chapter7/jasmine/spec/async.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/6/5. 3 | */ 4 | var foo = require("../src/exp1.js"); 5 | describe("async test", function() { 6 | it("tracks that the spy was called", function(done) { 7 | foo.getRequest("http://baidu.com",function(data){ 8 | expect(data.statusCode).toBe(200); 9 | done(); 10 | }); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /chapter2/2.8 stream/readline/readline.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/1/20. 3 | */ 4 | var readline = require("readline"); 5 | var fs = require("fs"); 6 | var rl = readline.createInterface({ 7 | input:fs.createReadStream("./foo.txt") 8 | }); 9 | 10 | rl.on("line", function(data){ 11 | console.log(data); 12 | }); 13 | 14 | rl.on("close",function(){ 15 | console.log("cloesd"); 16 | }) -------------------------------------------------------------------------------- /chapter8/domainFirstTry/test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/4/18. 3 | */ 4 | var http = require("http"); 5 | 6 | //首先启动domain.js 7 | //短时间内发起大量http请求,可以在进程管理器中监测到明显的内存上升 8 | for(var i=0;i<10000;i++){ 9 | http.get("http://localhost:3000",function(err,result){ 10 | 11 | }); 12 | } 13 | process.on("uncaughtException",function(err){ 14 | console.log(err) 15 | }); 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /chapter2/2.10 cluster/child_process/child_process.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/1/19. 3 | */ 4 | var child_process = require("child_process"); 5 | var worker = child_process.fork("worker.js",["args1"]); 6 | worker.on("exit",function(){ 7 | console.log("child process exit"); 8 | }); 9 | worker.send({hello:"child"}); 10 | worker.on("message",function(msg){ 11 | console.log("from child",msg); 12 | }) -------------------------------------------------------------------------------- /chapter3/3.3 array/fill.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/5/20. 3 | */ 4 | var a = new Array(5); 5 | console.log(a);//[ , , , , ] 6 | a.fill(0); 7 | console.log(a);//[ 0, 0, 0, 0, 0 ] 8 | 9 | 10 | // ES5 11 | var arr3 = Array.apply(null, new Array(5)) 12 | .map(function () { return 0 }); 13 | // [ 0, 0, 0, 0, 0 ] 14 | 15 | // ES6 16 | const arr4 = new Array(2).fill(0); 17 | // [ 0, 0, 0, 0, 0 ] 18 | 19 | -------------------------------------------------------------------------------- /appendix/Loa/context.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/5/11. 3 | */ 4 | module.exports = class Context{ 5 | constructor(req,res){ 6 | this.req = req; 7 | this.res = res; 8 | 9 | } 10 | print(){ 11 | console.log(this.req); 12 | console.log(this.res); 13 | } 14 | 15 | end(){ 16 | this.res.end("End"); 17 | } 18 | 19 | } 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /chapter3/3.4 Func/exp1.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/3/14. 3 | */ 4 | function func(...args){ 5 | for(let val of args){ 6 | console.log(val); 7 | } 8 | } 9 | func(1,2,3); 10 | 11 | //合并数组 12 | var arr = [1,2,3]; 13 | var arr2 = [4,5]; 14 | console.log([...arr,...arr2]);//[ 1, 2, 3, 4, 5 ] 15 | //将字符串转换为数组 16 | var name = [..."Lear"]; 17 | console.log(name);//[ 'L', 'e', 'a', 'r' ] 18 | //将多个参数传入函数,见上面的例子 -------------------------------------------------------------------------------- /chapter3/3.6 iterator/exp1.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/5/20. 3 | */ 4 | var Iter ={ 5 | [Symbol.iterator] : function () { 6 | return { 7 | next: function () { 8 | return {value: 1,done: true}; 9 | } 10 | }; 11 | } 12 | } 13 | 14 | var obj = new Iter[Symbol.iterator](); 15 | obj.next(); //{ value: 1, done: true } 16 | 17 | console.log(obj.next()); -------------------------------------------------------------------------------- /chapter4/4.4 Generator/auto_exec_V2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/5/9. 3 | */ 4 | 5 | function auto(Generator){ 6 | var gen = Generator(); 7 | 8 | function next(data){ 9 | var result = gen.next(data); 10 | //判断执行是否结束 11 | if(result.done) return result.value; 12 | result.value.then(function(data){ 13 | next(data) 14 | }) 15 | } 16 | next(); 17 | } -------------------------------------------------------------------------------- /chapter2/2.8 stream/exp2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/3/4. 3 | */ 4 | var stream = require("stream"); 5 | var fs = require("fs"); 6 | var readStream = fs.createReadStream("./test.txt","utf-8"); 7 | readStream.on("data",function(data){ 8 | console.log(data); 9 | }); 10 | readStream.on("close",function(){ 11 | console.log("closed"); 12 | }); 13 | readStream.on("error",function(){ 14 | console.log("error"); 15 | }); -------------------------------------------------------------------------------- /chapter2/2.9 event/exp4.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/3/4. 3 | */ 4 | var eventEmitter = require("events"); 5 | var myEmitter = new eventEmitter(); 6 | myEmitter.on("event",function(){ 7 | console.log("event"); 8 | }) 9 | myEmitter.on("event",function(){ 10 | console.log("event"); 11 | }) 12 | myEmitter.emit("event"); 13 | console.log(myEmitter.eventNames()); 14 | //打印结果 15 | // event 16 | // event 17 | // [ 'event' ] 18 | -------------------------------------------------------------------------------- /chapter8/try.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/6/24. 3 | */ 4 | var fs = require("fs"); 5 | 6 | //try/catch无法捕获错误,会出现Error: ENOENT: no such file or directory, open 'some file not exists.txt' 7 | //应该使用监听error事件的方式来处理 8 | try{ 9 | var readStream = fs.createReadStream("some file not exists.txt"); 10 | }catch(err){ 11 | console.log(err); 12 | } 13 | 14 | readStream.on("error",function(err){ 15 | console.log(err); 16 | }); 17 | -------------------------------------------------------------------------------- /appendix/redis/pub-sub/exp3.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/2/16. 3 | */ 4 | var redis = require("redis"); 5 | var client = redis.createClient(6379, "127.0.0.1"); 6 | client.on("error", function(err){ 7 | console.log(err); 8 | }); 9 | //client.subscribe("test"); 10 | client.on('message', function(channel,message){ 11 | console.log("channel:" + channel + ", msg:"+message); 12 | client.publish("client","finish"); 13 | 14 | }); 15 | -------------------------------------------------------------------------------- /chapter3/3.7 Object/setProto.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/5/23. 3 | */ 4 | var Person = function(name,age){ 5 | this.name = name; 6 | this.age = age; 7 | this.greed= function(){ 8 | console.log("Hello,I am ",this.name) 9 | } 10 | } 11 | 12 | function Student(){ 13 | 14 | } 15 | 16 | 17 | var stud = new Student(); 18 | Object.setPrototypeOf(stud,Person); 19 | console.log(stud.__proto__);//[Function: Person] 20 | 21 | 22 | -------------------------------------------------------------------------------- /chapter2/2.11 process/errorHandling.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/3/4. 3 | */ 4 | var eventEmitter = require("events"); 5 | var myEmitter = new eventEmitter(); 6 | 7 | 8 | process.on("uncaughtException",function(){ 9 | console.log("got error"); 10 | }) 11 | 12 | 13 | console.log(3/i); 14 | 15 | //var result = 3/0; 16 | //myEmitter.on("ReferenceError",function(){ 17 | // console.log("event"); 18 | //}) 19 | //myEmitter.emit("error",new Error("crash!")) -------------------------------------------------------------------------------- /chapter3/3.2 let & const/let.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/3/13. 3 | */ 4 | for(let i = 0; i<3;i++){} 5 | console.log(i);//undefined 6 | 7 | for(var i = 0;i<5;i++){} 8 | console.log(i);//5 9 | ///////////////////////////// 10 | let a =15; 11 | //let a= 5;//SyntaxError: Identifier 'a' has already been declared 12 | function scope(){ 13 | let a = 10; 14 | if(true){ 15 | let a = 5; 16 | } 17 | console.log(a);//10 18 | } 19 | scope(); 20 | -------------------------------------------------------------------------------- /chapter3/3.7 Object/exp1.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/5/23. 3 | */ 4 | var Person = function(name,age){ 5 | this.name = name; 6 | this.age = age; 7 | this.greed= function(){ 8 | console.log("Hello,I am ",this.name) 9 | } 10 | } 11 | 12 | function Student(){ 13 | 14 | } 15 | Student.prototype = Person; 16 | //Object.setPrototypeOf(Student,Person); 17 | 18 | var stud = new Student(); 19 | console.log(Object.getPrototypeOf(stud).name); -------------------------------------------------------------------------------- /chapter3/3.8 Class/__proto__.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Created by likai on 17/3/13. 4 | */ 5 | class Student{ 6 | constructor(name,sex){ 7 | this.name = name; 8 | this.sex = sex; 9 | this.getInfo = ()=>{ 10 | console.log("name:",this.name,"sex:",this.sex); 11 | } 12 | } 13 | } 14 | 15 | 16 | const stu = new Student(); 17 | stu.__proto__.sayHello = ()=>{ 18 | console.log("Hello"); 19 | } 20 | stu.sayHello(); 21 | 22 | 23 | -------------------------------------------------------------------------------- /chapter3/3.8 Class/static.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/1/24. 3 | */ 4 | class Person { 5 | static getName(){ 6 | return "Lear"; 7 | } 8 | } 9 | 10 | Person.getName();//Lear 11 | var person = new Person(); 12 | person.getName();//error! 13 | 14 | class Student extends Person{ 15 | static getName2(){ 16 | return super.getName() + ",Hi"; 17 | } 18 | } 19 | 20 | //var student = new Student(); //error 21 | console.log(Student.getName2()) -------------------------------------------------------------------------------- /chapter8/domainFirstTry/domain.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/4/18. 3 | */ 4 | const fs = require("fs"); 5 | const d = require('domain').create(); 6 | d.on('error', (er) => { 7 | //由于我们手动捕获了错误,因此进程不会退出,但这可能会引起严重的内存泄露 8 | //测试代码见test.js 9 | console.log('error, but oh well ${er.message}'); 10 | }); 11 | d.run(() => { 12 | require('http').createServer((req, res) => { 13 | console.log(undefinedObject.undefined); 14 | }).listen(3000); 15 | }); -------------------------------------------------------------------------------- /chapter2/2.4 http/simpleServer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/1/18. 3 | */ 4 | var http = require("http") 5 | var server = http.createServer(function(req,res){ 6 | res.writeHead(404, {'Content-Type': 'text/plain'}); 7 | res.end("Hello Node!") 8 | }); 9 | server.on("connection",function(req,res){ 10 | console.log("connected"); 11 | }) 12 | server.on("request",function(req,res){ 13 | console.log("request"); 14 | }); 15 | server.listen(3000); 16 | 17 | 18 | -------------------------------------------------------------------------------- /chapter3/generator/throw.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/4/10. 3 | */ 4 | function* generator() { 5 | try{ 6 | yield console.log( "Hello World"); 7 | }catch(e){ 8 | console.log(e) 9 | } 10 | console.log("test"); 11 | yield console.log("from Lear"); 12 | return "end"; 13 | }; 14 | //输出 15 | //Hello World 16 | //throw error 17 | //test 18 | //from Lear 19 | var gen = generator(); 20 | gen.next(); 21 | gen.throw("throw error"); 22 | -------------------------------------------------------------------------------- /chapter7/jasmine/spec/spy.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/3/11. 3 | */ 4 | 5 | var foo = require("../src/exp1.js"); 6 | describe("A spy, when configured to fake a series of return values", function() { 7 | beforeEach(function() { 8 | spyOn(foo,"getRequest") 9 | }); 10 | 11 | it("tracks that the spy was called", function() { 12 | foo.getRequest("http://baidu.com"); 13 | expect(foo.getRequest).toHaveBeenCalled(); 14 | }); 15 | 16 | }); -------------------------------------------------------------------------------- /chapter3/3.3 array/from.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/5/20. 3 | */ 4 | var a = {}; 5 | 6 | var i = 0; 7 | 8 | while(i < 10) { 9 | a[i] = i; 10 | i++; 11 | } 12 | a.length = i; 13 | 14 | var a1 = Array.prototype.slice.call(a);//需要增加call方法 15 | a1.push(10); //success 16 | console.log(a1);//[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] 17 | 18 | var a2 = Array.from(a);//注意,from不是定义在prototype上的 19 | a2.push(10); //success 20 | console.log(a2);//[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] -------------------------------------------------------------------------------- /chapter4/4.3 Promise/readFile_promise.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/6/27. 3 | */ 4 | var fs = require("fs"); 5 | 6 | function readFile_promises(path){ 7 | return new Promise(function(resolve, reject) { 8 | fs.readFile(path,"UTF-8",function(err,data){ 9 | if (data){ 10 | resolve(data); 11 | } else { 12 | reject(err); 13 | } 14 | }); 15 | }); 16 | } 17 | 18 | module.exports = readFile_promises; -------------------------------------------------------------------------------- /chapter2/2.10 cluster/child_process/spawn.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/5/4. 3 | */ 4 | var spawn = require('child_process').spawn; 5 | var ls = spawn('ls',['-lh', '/usr']); 6 | 7 | ls.stdout.on('data', function(data) { 8 | console.log("stdout:", data.toString()); 9 | }); 10 | 11 | ls.stderr.on('data', function(data) { 12 | console.log("stderr:", data.toString()); 13 | }); 14 | 15 | ls.on('close', function(code) { 16 | console.log("child process exited with code",code); 17 | }); 18 | 19 | -------------------------------------------------------------------------------- /chapter2/2.4 http/upload/upload.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 |
12 | 13 |
14 | 15 | 16 |
17 | 18 | -------------------------------------------------------------------------------- /chapter2/2.4 http/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 |
12 | 13 |
14 | 15 |
16 | 17 |
18 | 19 | 20 | -------------------------------------------------------------------------------- /chapter4/4.2 Callback&Cps&Async/Q/q.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/2/19. 3 | */ 4 | var q = require("q"); 5 | var fs= require("fs"); 6 | 7 | function fs_readFile (path){ 8 | var promise = q.nfcall(fs.readFile,path,"utf-8"); 9 | return promise; 10 | } 11 | var count = 1; 12 | 13 | fs_readFile("test1.txt").then(callback).then(callback).then(callback); 14 | 15 | function callback(data){ 16 | console.log(data); 17 | count++; 18 | return fs_readFile("test"+count+".txt") 19 | } 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /chapter2/2.5 tcp/exp1.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/5/3. 3 | */ 4 | var net = require('net'); 5 | var server = net.createServer(function(c) { 6 | // 'connection' listener 7 | console.log('client connected'); 8 | c.on('end', function() { 9 | console.log('client disconnected'); 10 | }); 11 | c.write('hello\r\n'); 12 | c.pipe(c); 13 | }); 14 | server.on('error', function(err) { 15 | throw err; 16 | }); 17 | server.listen(8124, function() { 18 | console.log('server bound'); 19 | }); -------------------------------------------------------------------------------- /chapter3/3.7 Object/iter.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/5/23. 3 | */ 4 | var obj ={ 5 | "name":"lear", 6 | "age":10, 7 | "sex":"male" 8 | } 9 | 10 | Object.defineProperty(obj, 'sex', { 11 | value: "male", 12 | enumerable: false 13 | }); 14 | 15 | for(var key in obj){ 16 | //name--lear 17 | //age--10 18 | console.log(key+"--"+obj[key]); 19 | } 20 | 21 | console.log(Object.keys(obj));//[ 'name', 'age' ] 22 | console.log(Object.getOwnPropertyNames(obj));//[ 'name', 'age', 'sex' ] 23 | -------------------------------------------------------------------------------- /chapter3/async/async.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/4/9. 3 | */ 4 | async function timeout(ms) { 5 | await new Promise((resolve) => { 6 | setTimeout(resolve, ms); 7 | }); 8 | } 9 | 10 | async function asyncPrint(ms) { 11 | for(let i =0;i<5;i++){ 12 | await timeout(ms); 13 | console.log(i); 14 | } 15 | } 16 | 17 | async function test(){ 18 | await asyncPrint(1000); 19 | console.log("---------"); 20 | await asyncPrint(2000); 21 | } 22 | 23 | test(); 24 | 25 | 26 | -------------------------------------------------------------------------------- /chapter4/4.3 Promise/async-read.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/10/29. 3 | */ 4 | /** 5 | * Created by likai on 17/1/21. 6 | */ 7 | var myReadFile = require("./readFile_promise"); 8 | 9 | myReadFile("./foo.txt").then(function(value){ 10 | console.log(value.toString()); 11 | return myReadFile("bar.txt") 12 | }).then(function(value){ 13 | console.log(value.toString()); 14 | return myReadFile("baz.txt") 15 | }).then(function(value){ 16 | console.log(value.toString()); 17 | }); 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /chapter2/2.2 buffer/exp2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/4/21. 3 | */ 4 | console.log(new Buffer('hello, world!').toString('base64')); 5 | // 转换成base64字符串:aGVsbG8sIHdvcmxkIQ== 6 | 7 | console.log(new Buffer('aGVsbG8sIHdvcmxkIQ==', 'base64').toString()); 8 | // 还原base64字符串:hello, world! 9 | 10 | console.log(new Buffer('hello, world!').toString('hex')); 11 | // 转换成十六进制字符串:68656c6c6f2c20776f726c6421 12 | 13 | console.log(new Buffer('68656c6c6f2c20776f726c6421', 'hex').toString()); 14 | // 还原十六进制字符串:hello, world! 15 | 16 | -------------------------------------------------------------------------------- /chapter3/3.8 Class/ES6_Class.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/1/22. 3 | */ 4 | class Person{ 5 | constructor(name,age){ 6 | this.name = name; 7 | this.age = age; 8 | } 9 | getInfo(){ 10 | return this.name+ ","+this.age 11 | } 12 | } 13 | 14 | var person = new Person("Lear","20"); 15 | console.log(person.constructor == Person.prototype.constructor);//true 16 | console.log(person.getInfo == Person.prototype.getInfo);//true 17 | console.log(person.getInfo()); 18 | 19 | module.exports = Person; -------------------------------------------------------------------------------- /chapter4/4.2 Callback&Cps&Async/async/series.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/5/24. 3 | */ 4 | var async = require("async"); 5 | var fs= require("fs"); 6 | function func1 (callback){ 7 | fs.readFile("1.txt","utf-8",callback); 8 | } 9 | 10 | function func2(callback){ 11 | fs.readFile("2.txt","utf-8",callback); 12 | } 13 | 14 | function func3(callback){ 15 | fs.readFile("3.txt","utf-8",callback); 16 | } 17 | 18 | async.series([func1,func2,func3],function(err,data){ 19 | console.log(data);//[ '1.txt', '2.txt', '3.txt' ] 20 | }) 21 | -------------------------------------------------------------------------------- /chapter4/4.2 Callback&Cps&Async/async/parallel.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/5/24. 3 | */ 4 | var async = require("async"); 5 | var fs= require("fs"); 6 | function func1 (callback){ 7 | fs.readFile("1.txt","utf-8",callback); 8 | } 9 | 10 | function func2(callback){ 11 | 12 | fs.readFile("2.txt","utf-8",callback); 13 | } 14 | 15 | function func3(callback){ 16 | fs.readFile("3.txt","utf-8",callback); 17 | } 18 | 19 | async.parallel([func1,func2,func3],function(err,data){ 20 | console.log(data);//[ '1.txt', '2.txt', '3.txt' ] 21 | }) -------------------------------------------------------------------------------- /chapter3/generator/auto_execute.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/6/24. 3 | */ 4 | 5 | function* Generator() { 6 | yield "Hello Node"; 7 | yield "From Lear"; 8 | return "end"; 9 | } 10 | 11 | var gen = Generator(); 12 | 13 | function auto_exec(gen){ 14 | function next(data){ 15 | var result = gen.next(data); 16 | //判断执行是否结束 17 | if(result.done) return result.value; 18 | result.value.then(function(data){ 19 | next(data) 20 | }) 21 | } 22 | 23 | next(); 24 | } 25 | 26 | auto_exec(gen); -------------------------------------------------------------------------------- /chapter2/2.10 cluster/exp2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/8/4. 3 | */ 4 | var cluster = require('cluster'); 5 | var data = 0;//这里定义数据不会被所有进程共享,各个进程有各自的内存区域 6 | if (cluster.isMaster) { //主进程 7 | var numCPUs = require('os').cpus().length; 8 | for (var i = 0; i < numCPUs; i++) { 9 | var worker = cluster.fork(); 10 | } 11 | data=5; 12 | console.log('DATA VALUE in MainProcess: %d ' , data); 13 | } else { //子进程,会被调用numCPUs次 14 | // data++; 15 | console.log('DATA VALUE in ChildProcess %d: %d ', cluster.worker.id, data);// 16 | } 17 | -------------------------------------------------------------------------------- /chapter4/4.4 Generator/resolve2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/6/27. 3 | */ 4 | 5 | function* Generator() { 6 | yield "Hello Node"; 7 | yield "From Lear" 8 | return "end" 9 | } 10 | var gen = Generator(); 11 | 12 | function auto_exec(gen){ 13 | 14 | function next(data){ 15 | var result = gen.next(data); 16 | //判断执行是否结束 17 | if(result.done) return result.value; 18 | result.value.then(function(data){ 19 | next(data) 20 | }) 21 | } 22 | 23 | next(); 24 | } 25 | 26 | auto_exec(gen); 27 | -------------------------------------------------------------------------------- /chapter5/return next.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/4/20. 3 | */ 4 | 5 | var ctx =1; 6 | var func1 = function (ctx,next){ 7 | return next();//试着把return去掉 8 | }; 9 | var func2 = function (ctx,next){ 10 | return next();//试着把return去掉 11 | }; 12 | var p = Promise.resolve( 13 | func1(ctx,function next(){ 14 | 15 | return Promise.resolve( 16 | func2(ctx,function next(){ 17 | return ++ctx; 18 | }) 19 | ) 20 | }) 21 | ); 22 | p.then(function(ctx){ 23 | console.log(ctx);//ctx的期望值为2 24 | }); 25 | 26 | -------------------------------------------------------------------------------- /chapter2/2.2 buffer/highwatermark.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/9/24. 3 | */ 4 | var rs = require("fs").createReadStream('test.txt', {highWaterMark: 10}); 5 | 6 | // var data = ''; 7 | // rs.on("data", function (chunk){ 8 | // data += chunk; 9 | // }); 10 | // rs.on("end", function () { 11 | // console.log(data); 12 | // }); 13 | 14 | var data = []; 15 | rs.on('data', function(chunk){ 16 | data.push(chunk); 17 | }); 18 | rs.on('end', function(){ 19 | var buf = Buffer.concat(data); 20 | console.log(buf.toString('utf-8')); 21 | }); 22 | 23 | 24 | -------------------------------------------------------------------------------- /chapter2/eventLoop/exp2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/9/27. 3 | */ 4 | 5 | /*-------下面是官方文档的例子----------*/ 6 | 7 | var timeoutScheduled = Date.now(); 8 | 9 | setTimeout(function () { 10 | var delay = Date.now() - timeoutScheduled; 11 | console.log(delay + "ms have passed since I was scheduled"); 12 | }, 100); 13 | 14 | fs.readFile('foo.txt', function(err,data){ 15 | var startCallback = Date.now(); 16 | // do something that will take 10ms... 17 | while (Date.now() - startCallback < 1000) { 18 | ; // do nothing 19 | } 20 | }); 21 | -------------------------------------------------------------------------------- /chapter4/4.4 Generator/auto_exec_V1.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/2/22. 3 | */ 4 | function* Generator() { 5 | yield "Hello Node"; 6 | return "end" 7 | } 8 | 9 | var gen = Generator(); 10 | 11 | function auto(Generator) { 12 | var gen = Generator(); 13 | while (gen.next().value != undefined) { 14 | gen.next(); 15 | } 16 | } 17 | // console.log(gen.next());//{ value: 'Hello Node', done: false } 18 | // console.log(gen.next());//{ value: 'end', done: true } 19 | // console.log(gen.next());//{ value: undefined, done: true } 20 | // 21 | 22 | -------------------------------------------------------------------------------- /chapter2/2.9 event/exp3.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/1/17. 3 | */ 4 | var fs = require("fs") 5 | var EventEmitter = require('events').EventEmitter; 6 | var event = new EventEmitter() 7 | //如果该文件不存在,将会尝试创建它 8 | fs.writeFile("./test.txt","Hello Node",{flag:"a",encoding:"utf8"},function(err){ 9 | if(err){ 10 | throw err; 11 | } 12 | event.emit("done"); 13 | }); 14 | 15 | event.on("done",function(){ 16 | var data = fs.readFile("test.txt",function(err,data){ 17 | if(err) throw err; 18 | console.log(data.toString()); 19 | }); 20 | }); 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /chapter2/2.4 http/http-client.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/3/4. 3 | */ 4 | var http = require("http"); 5 | http.get("http://blockchain.info/ticker",function(res){ 6 | var statusCode = res.statusCode; 7 | if(statusCode = 200){ 8 | //buffer一节已经提到过,试着修改下面的代码 9 | var result = ""; 10 | res.on("data",function(data){ 11 | result+=data; 12 | }) 13 | res.on("end",function(){ 14 | console.log(result.toString()); 15 | }); 16 | res.on("error",function(e){ 17 | console.log(e.message); 18 | }) 19 | } 20 | }) -------------------------------------------------------------------------------- /chapter2/2.9 event/exp2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/2/19. 3 | */ 4 | var eventEmitter = require("events"); 5 | var fs = require("fs"); 6 | var myEmitter = new eventEmitter(); 7 | var i=0 8 | var test =["test0.txt","test1.txt","test2.txt","test3.txt"] 9 | 10 | function read(path){ 11 | i++; 12 | fs.readFile(path,function(err,data){ 13 | console.log(data.toString()); 14 | myEmitter.emit("test"); 15 | }) 16 | } 17 | myEmitter.on("test",function(){ 18 | if(i>3){ 19 | return; 20 | process.exit() 21 | } 22 | read(test[i]) 23 | }) 24 | 25 | read(test[0]) -------------------------------------------------------------------------------- /chapter3/3.8 Class/ES5_Inherit.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/1/23. 3 | */ 4 | const Person = require('./ES5_Class'); 5 | 6 | function Student(name,age,sex){ 7 | this.name = name; 8 | this.age = age; 9 | this.sex = sex; 10 | } 11 | Student.prototype = new Person(); 12 | Student.prototype.getInfo = function(){ 13 | return this.name +","+this.age +","+this.sex; 14 | } 15 | var student = new Student("Kai","male","20"); 16 | console.log(student.getInfo()); 17 | 18 | console.log(Student.prototype.__proto__== Person.prototype);//true 19 | 20 | console.log(student.__proto__ == Student.prototype);//true 21 | 22 | -------------------------------------------------------------------------------- /chapter2/2.3 fs/stat.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/3/2. 3 | */ 4 | var fs = require("fs"); 5 | //fs.stat("foo.txt",function(err,result){ 6 | // if(err){ 7 | // console.log(err); 8 | // return; 9 | // } 10 | // console.log(result); 11 | //}); 12 | 13 | 14 | fs.open("foo.txt",'a',function(err,fd){ 15 | if(err){ 16 | console.log(err); 17 | return; 18 | } 19 | console.log(fd); 20 | fs.fstat(fd,function(err,result){ 21 | if(err){ 22 | console.log(err); 23 | return; 24 | } 25 | console.log(result); 26 | }) 27 | }) 28 | 29 | -------------------------------------------------------------------------------- /chapter3/3.4 Func/this.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/1/20. 3 | */ 4 | var date ={ 5 | year:2017, 6 | month:5, 7 | day:15, 8 | getTime:function(){ 9 | var self = this; 10 | var func1 = function(){ 11 | return self.year+"/"+self.month+"/"+self.day; 12 | }; 13 | // var func1 = ()=>this.year+"/"+this.month+"/"+this.day; 14 | return func1(); 15 | } 16 | } 17 | 18 | console.log(date.getTime()); 19 | 20 | 21 | 22 | function foo() { 23 | setTimeout(()=> { 24 | console.log(this.id); 25 | 26 | }, 100); 27 | } 28 | global.id = 21; 29 | foo(); 30 | -------------------------------------------------------------------------------- /chapter2/2.6 ssl/server.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/5/6. 3 | */ 4 | var fs = require('fs'); 5 | var https = require('https'); 6 | 7 | var options = { 8 | key:fs.readFileSync('server.pem'), 9 | cert :fs.readFileSync('server-cert.pem'), 10 | ca : [fs.readFileSync('client-cert.pem')], 11 | requestCert:true 12 | } 13 | 14 | var server = https.createServer(options,function(req,res){ 15 | var authorized = req.socket.authorized ? 'authorized' : 'unauthorized'; 16 | console.log(authorized); 17 | res.writeHead(200); 18 | res.write('Welcome'); 19 | res.end(); 20 | }) 21 | 22 | server.listen(3001); 23 | -------------------------------------------------------------------------------- /chapter4/4.3 Promise/async.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/6/27. 3 | */ 4 | var readFile_promise = require("./readFile_promise"); 5 | 6 | async function readFile(){ 7 | var result1 = await readFile_promise("foo.txt"); 8 | console.log(result1);// I am foo.txt 9 | var result2 = await readFile_promise("bar.txt"); 10 | console.log(result1);// I am foo.txt 11 | } 12 | readFile(); 13 | 14 | 15 | 16 | var obj={} 17 | obj.func=function(){ 18 | //console.log(this);//Object { func: [Function] } 19 | (function(){ 20 | console.log(this)//Window or Global 21 | })() 22 | } 23 | obj.func() 24 | 25 | //console.log(process); -------------------------------------------------------------------------------- /chapter2/2.3 fs/listFile.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/3/4. 3 | */ 4 | var fs = require("fs"); 5 | function getAllFileFromPath(path) { 6 | fs.readdir(path, function (err, res) { 7 | for (var subPath of res) { 8 | var statObj = fs.statSync(path + "/" + subPath); //这里使用了同步方法而非异步 9 | if (statObj.isDirectory()) {//判断是否为文件夹 10 | console.log("Dir:", subPath); 11 | getAllFileFromPath(path + "/" + subPath)//如果是文件夹,递归获取子文件夹中的文件列表 12 | } else { 13 | console.log("File:", subPath); 14 | } 15 | } 16 | }) 17 | } 18 | getAllFileFromPath(__dirname); -------------------------------------------------------------------------------- /chapter3/3.5 Set&Map/map.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/3/15. 3 | */ 4 | var obj = {"c":3}; 5 | var map = new Map([ 6 | ["a",1], 7 | ["b",2], 8 | [obj,3] 9 | ]); 10 | console.log(map.size);//map的元素数量 11 | console.log(map.has("a"));//判断是否存在键值对 12 | console.log(map.get("b"));//获取某个键值对的值 13 | map.set("d",4);//如果键值不存在,则增加新的键值对,否则覆盖原有值 14 | map.delete("d");//删除某个键值对,返回一个布尔值 15 | for(let key of map.keys()){ 16 | console.log(key); //a b {c:3} 17 | } 18 | for(let value of map.values()){ 19 | console.log(value);//1 2 3 20 | } 21 | for(let m of map.entries()){ 22 | console.log(m);//[ 'a', 1 ] [ 'b', 2 ] [ { c: 3 }, 3 ] 23 | } 24 | map.clear();//清空map 25 | -------------------------------------------------------------------------------- /chapter2/2.11 process/environment-variable.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/1/19. 3 | */ 4 | //环境变量 5 | console.log(process.env) 6 | console.log(process.getuid());//用户ID 7 | console.log(process.argv);//node 的命令行参数列表,argv[0]表示node,argv[1]表示当前文件路径 8 | console.log(process.pid);//进程ID 9 | console.log(process.cwd());//当前目录 10 | console.log(process.version);//Node版本 11 | 12 | 13 | //判断版本 14 | var version = process.version; 15 | if(version > "v6.0.0"){ 16 | console.log("Higher version than v6.0.0"); 17 | //then...... 18 | } 19 | 20 | //监听事件 21 | process.on("exit",function(){ 22 | console.log("process exit"); 23 | //then....... 24 | }) 25 | 26 | process.exit(); -------------------------------------------------------------------------------- /chapter2/2.6 ssl/client.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/5/6. 3 | */ 4 | var fs = require('fs'); 5 | var https = require('https'); 6 | 7 | 8 | var options = { 9 | key:fs.readFileSync('client.pem'), //加载客户端公钥 10 | cert :fs.readFileSync('client-cert.pem'), //加载客户端私钥 11 | ca : [fs.readFileSync('server-cert.pem')],//加载服务器证书 12 | hostname:"localhost", 13 | port:3001, 14 | path:'/', 15 | method:'GET' 16 | } 17 | 18 | var req = https.request(options,function(res){ 19 | res.on('data',function(data){ 20 | process.stdout.write(data); 21 | }) 22 | }); 23 | req.end(); 24 | 25 | req.on('error',function(err){ 26 | console.log(err); 27 | }) -------------------------------------------------------------------------------- /chapter4/4.2 Callback&Cps&Async/async/waterfall.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/5/24. 3 | */ 4 | var async = require("async"); 5 | var fs= require("fs"); 6 | function func1 (callback){ 7 | fs.readFile("1.txt","utf-8",callback); 8 | } 9 | 10 | function func2(value,callback){ 11 | console.log("上一个操作传入的值",value); 12 | fs.readFile("2.txt","utf-8",callback); 13 | } 14 | 15 | function func3(value,callback){ 16 | console.log("上一个操作传入的值",value); 17 | fs.readFile("3.txt","utf-8",callback); 18 | } 19 | 20 | async.waterfall([func1,func2,func3],function(err,data){ 21 | console.log(data); 22 | }) 23 | //输出结果 24 | // 上一个操作传入的值 1.txt 25 | // 上一个操作传入的值 2.txt 26 | // 3.txt -------------------------------------------------------------------------------- /appendix/Loa/test/example.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/5/11. 3 | */ 4 | var Loa = require("../application"); 5 | var app = new Loa(); 6 | 7 | async function timeout(ms) { 8 | await new Promise((resolve) => { 9 | 10 | setTimeout(resolve, ms); 11 | 12 | }); 13 | } 14 | 15 | var middleWare1 = async function (req,res) { 16 | for(let i =0;i<5;i++){ 17 | await timeout(1000); 18 | console.log(i); 19 | } 20 | } 21 | 22 | var middleWare2 =function (req,res) { 23 | 24 | console.log("I am Middleware2"); 25 | res.end(); 26 | } 27 | 28 | app.use(middleWare1,"middleware1"); 29 | 30 | app.use(middleWare2,"middleware2"); 31 | 32 | app.listen(8000); -------------------------------------------------------------------------------- /chapter2/2.6 ssl/client-csr.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE REQUEST----- 2 | MIIBmTCCAQICAQAwWTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx 3 | ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAGA1UEAwwJbG9j 4 | YWxob3N0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDawyXVdlkbA+oOVjda 5 | hO+m0tDkYmncrYQsSVweYhKXNpMHbz/09fc/EPO9jlC0xJLvsXPiEPQ2Lfae4xKM 6 | vjBXDFEbgjKWTcXOUeEkwe40YOlDmN6gX5dl3meaL7BNmEwqvgzpR4bP89VRTPIi 7 | tuCEDcijtSxUfEkoOnvHF4tcCwIDAQABoAAwDQYJKoZIhvcNAQELBQADgYEAuo6i 8 | PbaRgA9bWTd6K612a9Gw01LfRIQp9ilawU9U2g1XNTi2K4YNKC41l+aB8P2I5yba 9 | 3kAOLXbGMEIxdPbzYwPxYMMVulv3eRNIH3QOGmxLGMoyC7+Hf0YZU5cmRR7PrKvp 10 | vbnzs7ZHGMYwy6cztL/lipXBr4c37ioSCa6v0l4= 11 | -----END CERTIFICATE REQUEST----- 12 | -------------------------------------------------------------------------------- /chapter2/2.6 ssl/server-csr.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE REQUEST----- 2 | MIIBmTCCAQICAQAwWTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx 3 | ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAGA1UEAwwJbG9j 4 | YWxob3N0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCljz0TgXhJpSnL3mBr 5 | ZylORVyAzNowC2VopKVNV6ClLQ3DAUfbs+sFfBLy3dg11bOQEirz9Ne+B8/euV4F 6 | qSEeBl29dH6R3oJ0Sp0a/ICS9BCR1dfb2jai9pawc3G/X2g7vxy8poRbz5EDC2V4 7 | UDlUHdY4vRs5trlPa1d6OLVI9wIDAQABoAAwDQYJKoZIhvcNAQELBQADgYEAbpR3 8 | ZNA8QxYZCyJ6tcBiLR06BMhizhOSZL+0eVLC7V+8M9j3V0zBc3jGJk9T84AzYS/z 9 | 8oe0MIuijvKQ/qZ+KakHsr0RWqaLg9zxR3PSkyzwuYtef8aQJMV1lm/UA+GPSAD7 10 | ojxli79zBvqM1p0mJbf2OiiLIueZ9b52F9XVQ98= 11 | -----END CERTIFICATE REQUEST----- 12 | -------------------------------------------------------------------------------- /chapter3/async/promise.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/1/21. 3 | */ 4 | const fs = require("fs"); 5 | const readFile_promise = function(path){ 6 | var promise = new Promise(function(resolve, reject) { 7 | fs.readFile(path,function(err,data){ 8 | if (data){ 9 | resolve(data); 10 | } else { 11 | reject(err); 12 | } 13 | }); 14 | }); 15 | return promise; 16 | } 17 | 18 | module.exports = readFile_promise; 19 | 20 | async function readasync(){ 21 | var result = await readFile_promise("1.txt").then(function(result){ 22 | return result; 23 | }); 24 | 25 | } 26 | 27 | readasync() 28 | 29 | -------------------------------------------------------------------------------- /appendix/redis/exp1.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/2/15. 3 | */ 4 | var redis = require("redis"); 5 | var bluebird = require("bluebird"); 6 | 7 | bluebird.promisifyAll(redis.RedisClient.prototype); 8 | bluebird.promisifyAll(redis.Multi.prototype); 9 | 10 | var client = redis.createClient('6379', '127.0.0.1'); 11 | client.on("error", function(error) { 12 | console.log(error); 13 | }); 14 | client.on("ready",function(){ 15 | // console.log("ready"); 16 | }) 17 | 18 | client.set("name", "Lear", "EX",10,function (err, reply) { 19 | client.get("name", redis.print); 20 | setTimeout(function () { 21 | client.get("name", redis.print); 22 | },10000) 23 | 24 | }); 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /chapter3/3.8 Class/ES6_inherit.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/1/22. 3 | */ 4 | const Person = require("./ES6_Class"); 5 | 6 | class Student extends Person{ 7 | constructor(name,age,sex) { 8 | super(name, age); 9 | this.sex = sex; 10 | } 11 | getInfo(){ 12 | return super.getInfo()+","+this.sex 13 | } 14 | } 15 | var student = new Student("Lear","30","male"); 16 | 17 | 18 | console.log(student instanceof Student); //true 19 | console.log(Student.prototype);// Student {} 20 | 21 | console.log(student.__proto__=== Student.prototype); 22 | 23 | console.log(Student.__proto__ === Person.prototype.constructor);//true 24 | 25 | console.log(Student.__proto__ ==Person);//true 26 | 27 | 28 | -------------------------------------------------------------------------------- /chapter2/util/exp1.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/3/5. 3 | */ 4 | var util = require('util'); 5 | var EventEmitter = require('events'); 6 | 7 | //声明一个构造函数 8 | function MyEventEmitter() { 9 | EventEmitter.call(this);//调用父类构造函数 10 | } 11 | util.inherits(MyEventEmitter, EventEmitter);//继承EventEmitter类 12 | MyEventEmitter.prototype.publish = function(data) {//实现自定义的publish方法 13 | this.emit('data', data); 14 | }; 15 | const myEventEmitter = new MyEventEmitter(); 16 | myEventEmitter.on('data', function(data){ 17 | console.log('Received data:',data); 18 | }); 19 | myEventEmitter.publish('It works!'); 20 | 21 | console.log(myEventEmitter instanceof EventEmitter); 22 | console.log(MyEventEmitter.super_ === EventEmitter); 23 | 24 | -------------------------------------------------------------------------------- /chapter4/4.4 Generator/async.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/2/27. 3 | */ 4 | var fs = require("fs"); 5 | const myReadFile = function(path){ 6 | var promise = new Promise(function(resolve, reject) { 7 | fs.readFile(path,{encoding:"utf-8"},function(err,data){ 8 | if (data){ 9 | resolve(data); 10 | } else { 11 | reject(err); 12 | } 13 | }); 14 | }); 15 | return promise; 16 | } 17 | 18 | var asyncReadFile = async function () { 19 | var result1 = await readFile('../test1.txt'); 20 | var result2 = await readFile('../test2.txt'); 21 | console.log(result1.toString()); 22 | console.log(result2.toString()); 23 | }; 24 | asyncReadFile() -------------------------------------------------------------------------------- /appendix/redis/redis-promise.js: -------------------------------------------------------------------------------- 1 | 2 | var redis = require("redis"); 3 | var bluebird = require("bluebird"); 4 | 5 | bluebird.promisifyAll(redis.RedisClient.prototype); 6 | bluebird.promisifyAll(redis.Multi.prototype); 7 | 8 | var client = redis.createClient('6379', '127.0.0.1'); 9 | client.on("error", function(error) { 10 | console.log(error); 11 | }); 12 | client.on("ready",function(){ 13 | // console.log("ready"); 14 | }) 15 | 16 | client.setAsync('name',"Lear").then(function(res) { 17 | console.log(res); // => 'bar' 18 | }); 19 | 20 | 21 | 22 | async function redisTest(){ 23 | await client.setAsync('name',"Lear"); 24 | var result = await client.getAsync("name"); 25 | console.log(result); 26 | } 27 | 28 | redisTest(); -------------------------------------------------------------------------------- /appendix/redis/pub-sub/exp2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/2/16. 3 | */ 4 | var redis = require("redis"); 5 | var fs = require("fs"); 6 | var client = redis.createClient(6379,"127.0.0.1"); 7 | client.on("error",function(err){ 8 | console.log(err); 9 | }); 10 | var list = ["txt1.txt","txt2.txt","txt3.txt"]; 11 | var i=0; 12 | 13 | //client.subscribe("client"); 14 | 15 | client.on("ready",function(){ 16 | // console.log("ready"); 17 | fs.readFile("txt1.txt",function(err){ 18 | client.publish('test',"hello"); 19 | }) 20 | 21 | 22 | }); 23 | 24 | 25 | //client.on("message",function(channel,msg){ 26 | // i++; 27 | // if(i>2){ 28 | // process.exit(); 29 | // } 30 | // // read(list[i],client); 31 | //}) 32 | 33 | -------------------------------------------------------------------------------- /chapter4/4.2 Callback&Cps&Async/cps-callback.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/2/19. 3 | */ 4 | var fs = require("fs"); 5 | function callback1(err,data){ 6 | if(err){ 7 | console.log(err); 8 | }else{ 9 | console.log(data); 10 | fs.readFile("../test2.txt",{encoding:"utf-8"},callback2); 11 | } 12 | } 13 | function callback2(err,data){ 14 | if(err){ 15 | console.log(err); 16 | }else{ 17 | console.log(data); 18 | fs.readFile("../test3.txt",{encoding:"utf-8"},callback3); 19 | } 20 | } 21 | function callback3(err,data){ 22 | if(err){ 23 | console.log(err); 24 | }else{ 25 | console.log(data); 26 | } 27 | } 28 | fs.readFile("../test1.txt",{encoding:"utf-8"},callback1); -------------------------------------------------------------------------------- /chapter3/generator/return.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/4/10. 3 | */ 4 | //function* Generator() { 5 | // yield console.log("Hello Node"); 6 | // yield console.log("From Lear"); 7 | // return "end" 8 | //} 9 | //var gen = Generator(); 10 | //gen.next();//"Hello Node" 11 | //gen.return(); 12 | ////return()方法后面的next不会被执行 13 | //gen.next(); 14 | 15 | 16 | //function func1(x="Hello", y = 'Node') { 17 | // console.log(x, y); 18 | // let x = "hello"//SyntaxError: Identifier 'x' has already been declared 19 | // var y = "node"// 正常 20 | //} 21 | //func1(); 22 | 23 | 24 | function func(...args){ 25 | for(let val of args){ 26 | console.log(val); 27 | } 28 | } 29 | var args = [1,2,3] 30 | func(...args); 31 | 32 | console.log(process.EventEmitter) -------------------------------------------------------------------------------- /chapter3/generator/co.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/8/6. 3 | */ 4 | var co = require("co"); 5 | var readFile_promise = require("../promise/readFile_promise"); 6 | 7 | function auto_exec(gen){ 8 | function next(data){ 9 | var result = gen.next(data); 10 | //判断执行是否结束 11 | if(result.done) return result.value; 12 | result.value.then(function(data){ 13 | next(data) 14 | }) 15 | } 16 | 17 | next(); 18 | } 19 | 20 | 21 | 22 | 23 | function * gen(){ 24 | var result = yield readFile_promise("foo.txt"); 25 | console.log(result); 26 | var result2 = yield readFile_promise("bar.txt"); 27 | console.log(result2); 28 | return result 29 | } 30 | var g = gen(); 31 | 32 | var result = auto_exec(g) 33 | console.log(result); 34 | -------------------------------------------------------------------------------- /chapter4/4.3 Promise/error.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/4/23. 3 | */ 4 | var fs = require("fs"); 5 | 6 | //Promise.resolve(function(){ 7 | // throw new Error("error") 8 | //}) 9 | // //.catch(function(err){ 10 | //// console.log(err); 11 | ////}) 12 | // 13 | 14 | //var p = new Promise(resolve =>{ 15 | // resolve("Hello World"); 16 | // throw new Error('test'); 17 | //}); 18 | // 19 | //p.then(function(data){ 20 | // console.log(data); 21 | //}) 22 | //.catch(function(err){ 23 | //if(err){ 24 | // console.log(err); 25 | //} 26 | //}) 27 | 28 | var promise = new Promise(function(resolve, reject) { 29 | resolve("Hello World"); 30 | throw new Error("get error");//promise状态确定后再抛出错误,无效 31 | }); 32 | 33 | promise.catch(function(error) { console.log(error) }); 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /chapter2/2.4 http/proxy.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/5/1. 3 | */ 4 | var http = require("http"); 5 | var url = require("url"); 6 | 7 | http.createServer(function(req,res){ 8 | console.log(req.url); 9 | var options = url.parse(req.url); 10 | options.headers = req.headers; 11 | 12 | var proxyRequest = http.request(options,function(pres){ 13 | res.writeHead(pres.statusCode,pres.headers); 14 | pres.on('data',function (data) { 15 | res.write(data); 16 | }); 17 | pres.on('end',function () { 18 | // res.end(); 19 | }); 20 | 21 | }); 22 | 23 | req.on('data',function(data){ 24 | proxyRequest.write(data); 25 | }); 26 | 27 | req.on('end',function(){ 28 | proxyRequest.end(); 29 | }); 30 | 31 | }).listen(8080); 32 | 33 | 34 | -------------------------------------------------------------------------------- /chapter2/2.8 stream/exp1.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/3/4. 3 | */ 4 | var stream = require("stream"); 5 | var http = require("http"); 6 | var fs = require("fs"); 7 | var server = http.createServer(function(req,res){ 8 | if(req.url=="/"){ 9 | var fileList = fs.readdirSync("./"); 10 | res.writeHead(200,{"Content-type":"text/plain"}); 11 | res.end(fileList.toString()); 12 | } 13 | else{ 14 | var path = "."+req.url; 15 | try{ 16 | var readStream = fs.createReadStream(path).pipe(res); 17 | }catch(e){ 18 | res.end("file not exists"); 19 | } 20 | 21 | } 22 | }) 23 | var port = 3000; 24 | server.listen(port); 25 | console.log("Listening on 3000"); 26 | 27 | //处理异常 28 | process.on("uncaughtException",function(){ 29 | console.log("got error"); 30 | }) 31 | 32 | -------------------------------------------------------------------------------- /chapter2/2.6 ssl/client-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICKTCCAZICCQD1SaHR01OJRDANBgkqhkiG9w0BAQsFADBZMQswCQYDVQQGEwJB 3 | VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0 4 | cyBQdHkgTHRkMRIwEAYDVQQDDAlsb2NhbGhvc3QwHhcNMTcwNTA2MDEwMzA1WhcN 5 | MTcwNjA1MDEwMzA1WjBZMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0 6 | ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRIwEAYDVQQDDAls 7 | b2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANrDJdV2WRsD6g5W 8 | N1qE76bS0ORiadythCxJXB5iEpc2kwdvP/T19z8Q872OULTEku+xc+IQ9DYt9p7j 9 | Eoy+MFcMURuCMpZNxc5R4STB7jRg6UOY3qBfl2XeZ5ovsE2YTCq+DOlHhs/z1VFM 10 | 8iK24IQNyKO1LFR8SSg6e8cXi1wLAgMBAAEwDQYJKoZIhvcNAQELBQADgYEAfJOg 11 | +O1a1n5EczZdIZuvd2+F2AK5zrdSXKZhyOm1h1qgzEcp+mdkbIGbAMiXx3KnLB8/ 12 | C6Ur0dkRcTH9djXLspq1mmldNUuW45XTVovqwQbiRp8ZRfRirunbN4oETZ80RiUk 13 | LgEKcTW9HDYZwjzY/3JthrbscuR11W+k/Se9/SE= 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /chapter2/2.6 ssl/server-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICKTCCAZICCQDM6k69S1RnLDANBgkqhkiG9w0BAQsFADBZMQswCQYDVQQGEwJB 3 | VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0 4 | cyBQdHkgTHRkMRIwEAYDVQQDDAlsb2NhbGhvc3QwHhcNMTcwNTA2MDEwMjQyWhcN 5 | MTcwNjA1MDEwMjQyWjBZMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0 6 | ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRIwEAYDVQQDDAls 7 | b2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKWPPROBeEmlKcve 8 | YGtnKU5FXIDM2jALZWikpU1XoKUtDcMBR9uz6wV8EvLd2DXVs5ASKvP0174Hz965 9 | XgWpIR4GXb10fpHegnRKnRr8gJL0EJHV19vaNqL2lrBzcb9faDu/HLymhFvPkQML 10 | ZXhQOVQd1ji9Gzm2uU9rV3o4tUj3AgMBAAEwDQYJKoZIhvcNAQELBQADgYEAb7vS 11 | tkQHRhhyHYd0z6wopj1+6XOWHykrzGAgDEdARjgOoAg6sgWVBlbt1fMuL0Anr/BU 12 | QuybafDSvJ9wDDZvvm3HH8ZPVSDKyy4MpBqoGH3AcIl208xpzBpZydxjHQNIkd3A 13 | MT7kghwYMQmdaOt1XfcHPl6trCZO6YuuLQHdIXw= 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /chapter2/2.8 stream/inherit.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/7/4. 3 | */ 4 | var Readable = require('stream').Readable 5 | var util = require('util') 6 | 7 | util.inherits(MyReadable, Readable) 8 | 9 | function MyReadable(array) { 10 | //如果objectMode设置成false在消耗数据时会转换为buffer 11 | Readable.call(this,{objectMode:true}); 12 | this.array = array; 13 | } 14 | 15 | MyReadable.prototype._read = function() { 16 | if(this.array.length){ 17 | this.push(this.array.shift()); 18 | }else{ 19 | this.push(null); 20 | } 21 | } 22 | 23 | 24 | const array = ['a','b','c','d','e']; 25 | const read = new MyReadable(array); 26 | 27 | read.on("data",function(data){ 28 | console.log(data); 29 | }) 30 | read.on("end",function(){ 31 | console.log("end"); 32 | }) 33 | 34 | process.env.TZ = "America/New_York"; 35 | var date = new Date(); 36 | console.log(date); 37 | -------------------------------------------------------------------------------- /chapter3/3.6 iterator/exp2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/7/2. 3 | */ 4 | var arr = [1,2,3]; 5 | console.log(arr[Symbol.iterator]);//[Function: values] 6 | 7 | var set = new Set([1,2,3]); 8 | console.log(set[Symbol.iterator]);//[Function: values] 9 | 10 | var map = new Map([ 11 | ["a",1], 12 | ["b",2], 13 | ]); 14 | console.log(map[Symbol.iterator]);//[Function: entries] 15 | 16 | var str = "Hello Node"; 17 | console.log(str[Symbol.iterator]);//[Function: [Symbol.iterator]] 18 | 19 | 20 | var obj = {}; 21 | console.log(obj[Symbol.iterator]);//undefined,普通对象没有iterator接口 22 | 23 | 24 | var Iter ={ 25 | [Symbol.iterator] : function () { 26 | var i=0; 27 | return { 28 | next: function () { 29 | return ++i; 30 | } 31 | }; 32 | } 33 | }; 34 | console.log(Iter[Symbol.iterator]);//[Function: [Symbol.iterator]] 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /chapter4/4.4 Generator/co.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/2/27. 3 | */ 4 | var fs = require("fs"); 5 | var co = require("co"); 6 | const myReadFile = function(path){ 7 | var promise = new Promise(function(resolve, reject) { 8 | fs.readFile(path,{encoding:"utf-8"},function(err,data){ 9 | if (data){ 10 | resolve(data); 11 | } else { 12 | reject(err); 13 | } 14 | }); 15 | }); 16 | return promise; 17 | } 18 | function * gen(){ 19 | var result = yield myReadFile("../test1.txt"); 20 | console.log(result); 21 | var result2 = yield myReadFile("../test2.txt"); 22 | console.log(result2); 23 | } 24 | //var g = gen(); 25 | //var result=g.next(); 26 | //result.value.then(function(data){ 27 | // g.next(data).value.then(function(data){ 28 | // g.next(data) 29 | // }); 30 | //}) 31 | //; 32 | 33 | co(gen) 34 | -------------------------------------------------------------------------------- /chapter2/2.6 ssl/server.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIICXAIBAAKBgQCljz0TgXhJpSnL3mBrZylORVyAzNowC2VopKVNV6ClLQ3DAUfb 3 | s+sFfBLy3dg11bOQEirz9Ne+B8/euV4FqSEeBl29dH6R3oJ0Sp0a/ICS9BCR1dfb 4 | 2jai9pawc3G/X2g7vxy8poRbz5EDC2V4UDlUHdY4vRs5trlPa1d6OLVI9wIDAQAB 5 | AoGAbjXjN5fpZkUPhMpdL0I2Sgd8Y7V6zZ7YfAeWjtz1cN+EGLtChavImRcWWhx6 6 | MKQ464BcnZfxAmya4S5Ou7/x7cOmh+yrxxOUPJLNSz+jhS1rHep04EKF4dMjAWhb 7 | Xv4c7UWyg6uc4sESBX4xuzDW+mdwKbpdvciSebn7+R15+IECQQDTj6rdvJcwhaWd 8 | UPsIonYjIuZQ2GcAmHfq7hAM+Rb2Mk7bf9hhxyM+meGQWfs5tDVCKq36Uv929/vP 9 | Nu4OxEU3AkEAyFXpZpb1AlZN1azi+Th0y1ck3We/rm9Yjpu7RfPb2KwgZ+UPI4qA 10 | mGa9xYZv4DwdwiKqc09gcQhSJWQ0QPj6QQJBAMVU51JmGzu2HTEsnMqEBt9lKSDV 11 | iNXkYU4veacwG7vOVwGkMOebAIPesqebVpqPPXIXLyojioekbSrtmIULi2cCQHJs 12 | X3sxDY/gK2S38ovWKx9ZDr1G3LyM7E/HsxcpSZBf/8JXmmX6XaiuRgXj21KAA582 13 | nZRu6e6ligXBTfcuPgECQA10JpzvG11YabXoiLe4odcub15FrW5B4Y8BYrMmlYCU 14 | u46zN4Ud5YxUMTCtiNi9h17ESo0RBbiE2IDqGyrJk18= 15 | -----END RSA PRIVATE KEY----- 16 | -------------------------------------------------------------------------------- /chapter2/2.6 ssl/client.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIICXgIBAAKBgQDawyXVdlkbA+oOVjdahO+m0tDkYmncrYQsSVweYhKXNpMHbz/0 3 | 9fc/EPO9jlC0xJLvsXPiEPQ2Lfae4xKMvjBXDFEbgjKWTcXOUeEkwe40YOlDmN6g 4 | X5dl3meaL7BNmEwqvgzpR4bP89VRTPIituCEDcijtSxUfEkoOnvHF4tcCwIDAQAB 5 | AoGBAL8R/YSRJsiixZaaFSTZwVvK/CrODjpxz2TC+lOLQ0ORph+zOoBhKP+LdehV 6 | WgZZPyFds6J7PmHoCWTDXhtRrnNr5/lkfZle+3DjWeUDHkx5MCTbV88du5cOph/N 7 | H4p6qnEKW08uFE2ngLmGpKbZMANTNxarUbPOe8evdSfHv6hZAkEA7aMrYlp43+lj 8 | 8HksA52L7OzMaCp5zmD3OJ4AXsxf7Y0oeQb00k2aH2zOeRuoLkclKkMSQHE/K6Fs 9 | kKnOTuz49QJBAOuqma1G31+E5JHUMzygGOBEaDgezMvi4+bb4tow9PgnQ6/n2Ej3 10 | vJl0+IYbrTgWy2dxwZ77zTdKQaFvcOtl4P8CQQDgh4VcXqNK3RhChBrkJ52n9G2G 11 | FmwUZWXxJsiuyWfx6afOApabhhsTihjkMQ+M+kfRUKIUJWxMay9K2EZIKHtpAkAr 12 | ih1SUiG6uAaymo3MyZdO99R5addUY9rPMBi9TwYzQq3StfbTpFGH2ICB5mMeVbfG 13 | qNGo2cSUTnfJp5kpJG1pAkEA6N6nK1BvN0cqei9nE4/X1DS0CWTwVfRvur93disk 14 | aZjwih5T60+Bet1v3fVSxqBi4L9UPKjZ4Fz2O1ZCrsom5Q== 15 | -----END RSA PRIVATE KEY----- 16 | -------------------------------------------------------------------------------- /chapter2/2.4 http/static-serve.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/3/4. 3 | */ 4 | var http = require("http"); 5 | var fs = require("fs"); 6 | var server = http.createServer(function(req,res){ 7 | if(req.url=="/"){ 8 | //如果访问路径是localhost:3000,则显示文件列表 9 | var fileList = fs.readdirSync("./"); 10 | res.writeHead(200,{"Content-type":"text/plain"}); 11 | //将数组转换为字符串返回 12 | res.end(fileList.toString()); 13 | } 14 | else{ 15 | var path = req.url; 16 | //在路径字符串前加.表示当前目录,避免在*nix系统下访问”/“文件夹 17 | fs.readFile("."+path,function(err,data){ 18 | if(err){ 19 | //如果该文件不存在,抛出异常 20 | res.end("Internal Error") 21 | throw err; 22 | } 23 | res.writeHead(200,{"Content-type":"text/plain"}) 24 | res.end(data); 25 | }) 26 | } 27 | }) 28 | var port = 3000; 29 | server.listen(port); 30 | console.log("Listening on 3000"); 31 | 32 | //处理异常 33 | process.on("uncaughtException",function(){ 34 | console.log("got error"); 35 | }) 36 | 37 | -------------------------------------------------------------------------------- /chapter4/4.3 Promise/promise.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/5/18. 3 | */ 4 | 5 | var promises = ["foo.txt","bar.txt","baz.txt"].map(function (path) { 6 | return readFile_promise(path); 7 | }); 8 | 9 | Promise.all(promises).then(function (results) { 10 | console.log(results); //results的内容是文本文件内容的顺序排列 11 | }).catch(function(err){ 12 | // ... 13 | }); 14 | 15 | 16 | ////////////////////////////////////////////////////// 17 | function timeout(msg) { 18 | return new Promise((resolve, reject) => { 19 | setTimeout(resolve, 1000, msg); 20 | }); 21 | } 22 | timeout(1000).then(function(value){ 23 | return new Promise((resolve, reject) => { 24 | setTimeout(resolve, 1000, '1000ms passed'); 25 | }); 26 | }).then(function(value){ 27 | console.log(value); // 1000ms passed 28 | }); 29 | 30 | ////////////////////////////////////// 31 | var promise = new Promise((resolve, reject) => { 32 | console.log('begin'); 33 | resolve(); 34 | }); 35 | 36 | setTimeout(() => { 37 | promise.then(() => { 38 | console.log('end'); 39 | }) 40 | }, 5000); 41 | 42 | 43 | -------------------------------------------------------------------------------- /appendix/Loa/application.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/5/10. 3 | */ 4 | const Context = require('./context'); 5 | const Emitter = require('events'); 6 | const http = require("http"); 7 | 8 | module.exports = class Loa extends Emitter{ 9 | constructor(){ 10 | super(); 11 | this.middleware= []; 12 | this.nameList=[]; 13 | } 14 | 15 | use(fn,name){ 16 | this.middleware.push(fn); 17 | this.nameList.push(name); 18 | 19 | } 20 | 21 | 22 | async compose(req,res){ 23 | var con = new Context(req,res); 24 | 25 | for(let i =0 ;i{ 36 | this.compose(req,res); 37 | }); 38 | return server.listen(port,function(){ 39 | console.log("Listening on",port); 40 | }); 41 | } 42 | } 43 | 44 | -------------------------------------------------------------------------------- /appendix/Loa/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 likaiboy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /chapter2/2.11 process/myTimeZone.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/4/30. 3 | */ 4 | 5 | process.env.TZ = "Asia/Shanghai"; 6 | 7 | 8 | Date.prototype.TimeZone = new Map([ 9 | //书籍出版时没有注意到,这里存在错误 10 | //原书代码中上海的时区写成了-8,纽约则是写成了+5 11 | //非常抱歉😞 12 | ['Europe/London',0], 13 | ['Asia/Shanghai',8], 14 | ['America/New_York',-5] 15 | ]) 16 | Date.prototype.zoneDate = function(){ 17 | if(process.env.TZ == undefined){ 18 | return new Date(); 19 | }else{ 20 | for (let item of this.TimeZone.entries()) { 21 | if(item[0] == process.env.TZ){ 22 | let d = new Date(); 23 | d.setHours(d.getHours()+item[1]); 24 | return d; 25 | } 26 | } 27 | return new Date(); 28 | } 29 | } 30 | 31 | var date = new Date().zoneDate(); 32 | console.log(date); 33 | 34 | // Date对象的一些其他方法 35 | // console.log(date.toLocaleString());//4/30/2017, 10:44:10 PM 本地时间 36 | // console.log(date.toGMTString());//Sun, 30 Apr 2017 14:44:10 GMT 世界时间 37 | // console.log(date.toUTCString());//推荐使用toUTCString进行代替toGMTString,二者返回结果相同 38 | //获得当前时区 39 | //console.log(date.getTimezoneOffset()); 40 | 41 | 42 | -------------------------------------------------------------------------------- /chapter3/3.6 iterator/myIter.js: -------------------------------------------------------------------------------- 1 | function myIter(array){ 2 | this.array =array; 3 | } 4 | 5 | myIter.prototype[Symbol.iterator] = function() { 6 | //var self = this;//下面使用箭头函数,可以省去this的指向问题 7 | let index = 0; 8 | var next = ()=> { 9 | if (index < this.array.length) { 10 | return { 11 | value: this.array[index++], 12 | done: false 13 | }; 14 | } else { 15 | return { value: undefined, done: true }; 16 | } 17 | } 18 | return { next: next }; 19 | } 20 | 21 | var myiter = new myIter(["a","b"]) 22 | 23 | for(var i of myiter){ 24 | console.log(i); 25 | } 26 | 27 | 28 | let obj = { 29 | data: [ 'hello', 'world' ], 30 | [Symbol.iterator]() { 31 | const self = this; 32 | let index = 0; 33 | return { 34 | next() { 35 | if (index < self.data.length) { 36 | return { 37 | value: self.data[index++], 38 | done: false 39 | }; 40 | } else { 41 | return { value: undefined, done: true }; 42 | } 43 | } 44 | }; 45 | } 46 | }; 47 | for (var i of obj){ 48 | console.log(i); 49 | } -------------------------------------------------------------------------------- /chapter8/cluster.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/4/18. 3 | */ 4 | 5 | const cluster = require('cluster'); 6 | const domain = require('domain'); 7 | const http = require('http'); 8 | 9 | if (cluster.isMaster) { 10 | //新建两个worker进程 11 | cluster.fork(); 12 | cluster.fork(); 13 | //当http访问出错时,会有一个worker退出,再新建一个worker进程 14 | cluster.on('disconnect', (worker) => { 15 | console.error('disconnect!'); 16 | cluster.fork(); 17 | }); 18 | } else { 19 | const server = http.createServer((req, res) => { 20 | const d = domain.create(); 21 | d.on('error', (er) => { 22 | console.error(`error ${er.stack}`); 23 | //停止接收新的请求 24 | server.close(); 25 | //触发cluster的disconnect事件 26 | cluster.worker.disconnect(); 27 | 28 | res.statusCode = 500; 29 | res.setHeader('content-type', 'text/plain'); 30 | res.end('Oops, there was a problem!\n'); 31 | process.exit(1); 32 | }); 33 | d.add(req); 34 | d.add(res); 35 | d.run(() => { 36 | handleRequest(req, res); 37 | }); 38 | }); 39 | server.listen(3000); 40 | } 41 | 42 | 43 | function handleRequest(req, res) { 44 | switch (req.url) { 45 | case '/error': 46 | //通过访问undefined的属性,确保在异步回调时出错 47 | setTimeout(() => { 48 | console.log(foo.bar) 49 | }); 50 | break; 51 | default: 52 | res.end('ok'); 53 | } 54 | } 55 | 56 | 57 | -------------------------------------------------------------------------------- /chapter2/2.4 http/upload/upload.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/3/5. 3 | */ 4 | var http = require("http"); 5 | var fs = require("fs"); 6 | var formidable = require("formidable"); 7 | 8 | var server = http.createServer(function(req,res){ 9 | if(req.url == "/upload"){ 10 | switch (req.method){ 11 | case "POST": 12 | dealUpload(req,res); 13 | break; 14 | case "GET": 15 | fs.createReadStream("upload.html").pipe(res); 16 | break; 17 | } 18 | } 19 | }); 20 | function dealUpload(req,res){ 21 | var form = new formidable.IncomingForm();//创建Formidable.IncomingForm对象 22 | form.keepExtensions = true;//保持原有的扩展名 23 | form.uploadDir = __dirname;//上传目录为当前目录 24 | form.parse(req,function(err,fields,files){ 25 | if(err){throw err;} 26 | console.log(fields);//{ submit: 'submit' } 27 | console.log(files); 28 | res.writeHead(200, {"content-type": 'text/plain'}); 29 | res.end('upload finished'); 30 | }) 31 | } 32 | server.listen(3000); 33 | 34 | 35 | //{ file:File 36 | // { 37 | // domain: null, 38 | // _events: {}, 39 | // _eventsCount: 0, 40 | // _maxListeners: undefined, 41 | // size: 2978715, 42 | // path: '/Users/likai/Desktop/workpace/BookExample/chapter2/http/upload_0382661bc1e2f959d1dfc7e936df6c0d.m4a', 43 | // name: '未命名 2.m4a', 44 | // type: 'audio/x-m4a', 45 | // hash: null, 46 | // lastModifiedDate: 2017-03-05T03:12:30.578Z, 47 | // _writeStream: 48 | //}} -------------------------------------------------------------------------------- /chapter7/jasmine/spec/exp1.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/3/8. 3 | */ 4 | require("jasmine"); 5 | describe("A suite", function() { 6 | it("contains spec with an expectation", function() { 7 | expect(true).toBe(true); 8 | }); 9 | }); 10 | 11 | /* 12 | * toEqual 13 | * toBeGreaterThan 14 | * toBeLessThan 15 | * toContain 16 | * toBeFalsy 17 | * toBeTruthy 18 | * toBeUndefined 19 | * toBeDefined 20 | * toBeNull 21 | * toMatch 22 | * toBe 23 | * */ 24 | 25 | describe("A suite is just a function", function() { 26 | var a; 27 | 28 | it("and so is a spec", function() { 29 | a = true; 30 | 31 | expect(a).toBe(true); 32 | }); 33 | }); 34 | 35 | 36 | 37 | 38 | describe("A spy, when configured to fake a series of return values", function() { 39 | var foo, bar; 40 | 41 | beforeEach(function() { 42 | foo = { 43 | setBar: function(value) { 44 | bar = value; 45 | }, 46 | getBar: function() { 47 | return bar; 48 | } 49 | }; 50 | 51 | spyOn(foo, "getBar").and.returnValues("fetched first", "fetched second"); 52 | 53 | foo.setBar(123); 54 | }); 55 | 56 | it("tracks that the spy was called", function() { 57 | foo.getBar(123); 58 | expect(foo.getBar).toHaveBeenCalled(); 59 | }); 60 | 61 | it("should not affect other functions", function() { 62 | expect(bar).toEqual(123); 63 | }); 64 | 65 | it("when called multiple times returns the requested values in order", function() { 66 | expect(foo.getBar()).toEqual("fetched first"); 67 | expect(foo.getBar()).toEqual("fetched second"); 68 | expect(foo.getBar()).toBeUndefined(); 69 | }); 70 | }); -------------------------------------------------------------------------------- /chapter4/4.5 async&awiat/exp.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 2017/5/8. 3 | */ 4 | 5 | async function myReadFile(path){ 6 | var promise = new Promise(function(resolve, reject) { 7 | require("fs").readFile(path,"utf-8",function(err,data){ 8 | if (data){ 9 | resolve(data); 10 | } else { 11 | reject(err); 12 | } 13 | }); 14 | }); 15 | return promise; 16 | } 17 | 18 | 19 | 20 | // async function readFile(){ 21 | // var result1 = await myReadFile("1.txt"); 22 | // console.log(result1);// I am 1.txt 23 | // var result2 = await myReadFile("2.txt"); 24 | // console.log(result1);// I am 1.txt 25 | // } 26 | // readFile(); 27 | // 28 | // //等价于下面的代码 29 | // 30 | // myReadFile("1.txt").then(function(value){ 31 | // console.log(value.toString()); 32 | // return myReadFile("2.txt") 33 | // }).then(function(value){ 34 | // console.log(value.toString()); 35 | // }) 36 | 37 | 38 | 39 | async function readFile() { 40 | const [result1, result2] = await Promise.all([ 41 | myReadFile("1.txt"), 42 | myReadFile("2.txt"), 43 | ]); 44 | console.log(result1, result2); 45 | } 46 | 47 | // 等价于下面的代码 48 | function readFile() { 49 | return Promise.all([ 50 | myReadFile("1.txt"), 51 | myReadFile("2.txt"), 52 | ]) 53 | .then((result) => { 54 | console.log(result); 55 | }); 56 | } 57 | 58 | 59 | 60 | async function readFile() { 61 | try { 62 | await myReadFile(a-path-not-exists); 63 | } catch (err) { 64 | console.error(err); 65 | } 66 | } 67 | 68 | // 等价于下面的代码 69 | function asyncFunc() { 70 | return myReadFile(a-path-not-exists) 71 | .catch(err => { 72 | console.error(err); 73 | }); 74 | } 75 | 76 | 77 | async function readFile(){ 78 | for(let i= 1;i<5;i++ ){ 79 | var result = await myReadFile(i+'.txt'); 80 | console.log(result); 81 | } 82 | } 83 | 84 | async function readFile(list){ 85 | list.forEach(async function(item){ 86 | var result = await myReadFile(item); 87 | console.log(result); 88 | }) 89 | } 90 | 91 | /*-------------------------------------------------*/ 92 | async function readFile3(list){ 93 | for(var item of list){ 94 | var result = await myReadFile(item); 95 | console.log(result); 96 | } 97 | } 98 | //readFile3(['1.txt','2.txt','3.txt','4.txt']) 99 | 100 | async function readFile4(list){ 101 | await Promise.all(list.map(async function(item){ 102 | var result = await myReadFile(item); 103 | console.log(result); 104 | })); 105 | } 106 | readFile4(['1.txt','2.txt','3.txt','4.txt']) -------------------------------------------------------------------------------- /chapter7/jasmine/spec/exp2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by likai on 17/3/11. 3 | */ 4 | describe("The 'toBe' matcher compares with ===", function() { 5 | it("and has a positive case", function() { 6 | expect(true).toBe(true); 7 | }); 8 | it("and can have a negative case", function() { 9 | expect(false).not.toBe(true); 10 | }); 11 | 12 | it("The 'toBe' matcher compares with ===", function() { 13 | var a = 12; 14 | var b = a; 15 | 16 | expect(a).toBe(b); 17 | expect(a).not.toBe(null); 18 | }); 19 | 20 | it("works for simple literals and variables", function() { 21 | var a = 12; 22 | expect(a).toEqual(12); 23 | }); 24 | it("The `toBeUndefined` matcher compares against `undefined`", function() { 25 | var a = { 26 | foo: "foo" 27 | }; 28 | 29 | expect(a.foo).not.toBeUndefined(); 30 | expect(a.bar).toBeUndefined(); 31 | }); 32 | 33 | it("The 'toBeNull' matcher compares against null", function() { 34 | var a = null; 35 | var foo = "foo"; 36 | 37 | expect(null).toBeNull(); 38 | expect(a).toBeNull(); 39 | expect(foo).not.toBeNull(); 40 | }); 41 | 42 | it("works for finding an item in an Array", function() { 43 | var a = ["foo", "bar", "baz"]; 44 | 45 | expect(a).toContain("bar"); 46 | expect(a).not.toContain("quux"); 47 | }); 48 | 49 | it("also works for finding a substring", function() { 50 | var a = "foo bar baz"; 51 | 52 | expect(a).toContain("bar"); 53 | expect(a).not.toContain("quux"); 54 | }); 55 | 56 | it("The 'toBeLessThan' matcher is for mathematical comparisons", function() { 57 | var pi = 3.1415926, 58 | e = 2.78; 59 | 60 | expect(e).toBeLessThan(pi); 61 | expect(pi).not.toBeLessThan(e); 62 | }); 63 | 64 | }); 65 | 66 | 67 | describe("Included matchers:", function() { 68 | 69 | 70 | 71 | describe("The 'toEqual' matcher", function() { 72 | 73 | 74 | 75 | it("should work for objects", function() { 76 | var foo = { 77 | a: 12, 78 | b: 34 79 | }; 80 | var bar = { 81 | a: 12, 82 | b: 34 83 | }; 84 | expect(foo).toEqual(bar); 85 | }); 86 | }); 87 | 88 | it("The 'toMatch' matcher is for regular expressions", function() { 89 | var message = "foo bar baz"; 90 | 91 | expect(message).toMatch(/bar/); 92 | expect(message).toMatch("bar"); 93 | expect(message).not.toMatch(/quux/); 94 | }); 95 | 96 | it("The 'toBeDefined' matcher compares against `undefined`", function() { 97 | var a = { 98 | foo: "foo" 99 | }; 100 | 101 | expect(a.foo).toBeDefined(); 102 | expect(a.bar).not.toBeDefined(); 103 | }); 104 | 105 | 106 | 107 | it("The 'toBeTruthy' matcher is for boolean casting testing", function() { 108 | var a, foo = "foo"; 109 | 110 | expect(foo).toBeTruthy(); 111 | expect(a).not.toBeTruthy(); 112 | }); 113 | 114 | it("The 'toBeFalsy' matcher is for boolean casting testing", function() { 115 | var a, foo = "foo"; 116 | 117 | expect(a).toBeFalsy(); 118 | expect(foo).not.toBeFalsy(); 119 | }); 120 | 121 | describe("The 'toContain' matcher", function() { 122 | it("works for finding an item in an Array", function() { 123 | var a = ["foo", "bar", "baz"]; 124 | 125 | expect(a).toContain("bar"); 126 | expect(a).not.toContain("quux"); 127 | }); 128 | 129 | it("also works for finding a substring", function() { 130 | var a = "foo bar baz"; 131 | 132 | expect(a).toContain("bar"); 133 | expect(a).not.toContain("quux"); 134 | }); 135 | }); 136 | 137 | it("The 'toBeLessThan' matcher is for mathematical comparisons", function() { 138 | var pi = 3.1415926, 139 | e = 2.78; 140 | 141 | expect(e).toBeLessThan(pi); 142 | expect(pi).not.toBeLessThan(e); 143 | }); 144 | 145 | it("The 'toBeGreaterThan' matcher is for mathematical comparisons", function() { 146 | var pi = 3.1415926, 147 | e = 2.78; 148 | 149 | expect(pi).toBeGreaterThan(e); 150 | expect(e).not.toBeGreaterThan(pi); 151 | }); 152 | 153 | it("The 'toBeCloseTo' matcher is for precision math comparison", function() { 154 | var pi = 3.1415926, 155 | e = 2.78; 156 | 157 | expect(pi).not.toBeCloseTo(e, 2); 158 | expect(pi).toBeCloseTo(e, 0); 159 | }); 160 | 161 | it("The 'toThrow' matcher is for testing if a function throws an exception", function() { 162 | var foo = function() { 163 | return 1 + 2; 164 | }; 165 | var bar = function() { 166 | return a + 1; 167 | }; 168 | var baz = function() { 169 | throw 'what'; 170 | }; 171 | 172 | expect(foo).not.toThrow(); 173 | expect(bar).toThrow(); 174 | expect(baz).toThrow('what'); 175 | }); 176 | 177 | it("The 'toThrowError' matcher is for testing a specific thrown exception", function() { 178 | var foo = function() { 179 | throw new TypeError("foo bar baz"); 180 | }; 181 | 182 | expect(foo).toThrowError("foo bar baz"); 183 | expect(foo).toThrowError(/bar/); 184 | expect(foo).toThrowError(TypeError); 185 | expect(foo).toThrowError(TypeError, "foo bar baz"); 186 | }); 187 | }); --------------------------------------------------------------------------------