nodejs design patterns 130602183400 phpapp02
TRANSCRIPT
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
1/76
Node.js PatternsFor the Discerning Developer
C. Aaron Cois, Ph.D. :: Carnegie Mellon University, SE
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
2/76
Me
!aaroncois
""".codehenge.net
gith#$.co%&cacois
Disclaimer: Though I am an employee of the Software Engineering Institute at Carnegie Mellon University,this work was not fune !y the SEI an oes not re"ect the work or opinions of the SEI or its customers#
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
3/76
'et(s tal) a$o#t
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
4/76
Node.js *asics
• +avaScript
• Asynchrono#s
• Non$loc)ing &-
• Eventdriven
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
5/76
So, +avaScript
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
6/76
/he *asics
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
7/76
Prototype$ased Progra%%ing
• +avaScript has no classes
• nstead, 0#nctions de1ne o$jects
function Person() {}
var p = new Person();
%age: http:&&tech2.in.co%&0eat#res&ga%ing&1ve"ac)yga%inghard"aretoloo)0or"ardto&345672
$rototype
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
8/76
Classless Progra%%ing
8hat do classes do 0or #s
• De1ne local scope & na%espace
• Allo" private attri$#tes & %ethods
• Encaps#late code
•
-rgani9e applications in an o$jectoriented "ay
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
9/76
Prototype$ased Progra%%ing
function Person(firstname, lastname){ this.firstnam e = firstname; this.lastnam e = lastname;
}
var p = new Person(“Philip”, “Fry”);
8hat else can do that
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
10/76
Prototype nheritance
function Person(firstname, lastname){ this.firstnam e = firstname; this.lastnam e = lastname; } %% Create new class
Employee = Person; %%Inherit from superclass
Employee.prototype = { marital_status: 'single',
salute: function() { return 'M y nam e is ' + this.firstname; } }
var p = new Employee (“Philip”, “Fry”);
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
11/76
8atch o#t
function Person(firstname, lastname){ this.firstnam e = firstname; this.lastnam e = lastname; } %% Create new class Employee = Person; %%Inherit from superclass
Employee.prototype = { marital_status: 'single',
salute: function() { return 'M y nam e is ' + this.firstname; } }
var p = new Employee (“Philip”, “Fry”);
/he ;ne"( is very i%portant
0 yo# 0orget, yo#r ne" o$ject"ill have glo$al scope internally
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
12/76
Another option
function Person(firstname, lastname){ this.firstnam e = firstname; this.lastnam e = lastname; } Employee = Person; %%Inherit from superclass
Employee.prototype = { marital_status: 'single',
salute: function() { return 'M y nam e is ' + this.firstname;
} }
var p = Object.create(Employee); p.firstname = 'Philip'; p.lastname = 'Fry';
8or)s, $#t yo# can(t initiali9eattri$#tes in constr#ctor
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
13/76
AntiPattern: +avaScript %ports
• Spread code aro#nd 1les
• 'in) li$raries
• No "ay to %aintain private localscope&state&na%espace
•
'eads to: – Na%e collisions
– Unnecessary access
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
14/76
Pattern: Mod#les
• An elegant "ay o0 encaps#lating andre#sing code
• Adapted 0ro%
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
15/76
Mod#les in the 8ild
var http = require('http'),
io = require('socketio'),
_ = require('!n"erscore');
0 yo#(ve progra%%ed in Node, this
loo)s 0a%iliar
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
16/76
Anato%y o0 a %od#le
var privateVal = '# am Pri$ate%';
module.e&ports = { answer: ,
add: function(x, y) {
return x + y;
}
}
%y%od#le.js
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
17/76
Usage
mod = require('m ym o"!le');
console.log('*he ans er: '+ mod.ans er);
var sum = mod.a""(,);
console.log('-!m : ' + sum);
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
18/76
Mod#les are #sed every"here
%% User moel var mongoose = require('m ongoose')
, Schema = mongoose.-chem a;
var userSchema = new Schema({
nam e: {type: String, required: true},
email: {type: String, required: true}, githubid: String,
twitterid: String,
dateCreated: {type: Date, default: Date.no }
});
userSchema.m etho"s.$ali"Passor" = function validPass(pass) {
%% valiate passwor&
}
module.e&ports = mongoose.m o"el('.ser', userSchema);
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
19/76
My con1g 1les Mod#les.
var config = require('config/s');
console.log('0onfig!re" !ser is: ' + config.user);
module.e&ports = {
user: 'm a!ricem oss'
}
con1g.js
app.js
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
20/76
Asynchrono#s
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
21/76
Asynchrono#s Progra%%ing
• Node is entirely asynchrono#s
•
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
22/76
Event 'oop
Node.jsEvent
'oop
Node app
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
23/76
Event 'oop
Node.jsEvent
'oop
Node apps pass asynctas)s to the eventloop, along "ith a
call$ac)
>0#nction, call$ac)?
Node app
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
24/76
Event 'oop
Node.jsEvent
'oop
/he event loop e@ciently%anages a thread pool andeec#tes tas)s e@cientlyB
/hread4
/hread2
/hreadn
B /as) 4
/as) 2
/as) 3
/as) 7
et#rn 4
Call$ac)4>?
Band eec#tes eachcall$ac) as tas)s co%plete
Node app
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
25/76
Async &-
/he 0ollo"ing tas)s sho#ld $e doneasynchrono#sly, #sing the event loop:
• &- operations
• eavy co%p#tation
•
Anything re#iring $loc)ing
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
26/76
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
27/76
Antipattern: Synchrono#s Code
for (var i = 1; i 2 311111; i+ + ){
4o anything
}
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
28/76
Antipattern: Synchrono#s Code
*#t "hy "o#ld yo# do that
ood #estion.
*#t in other lang#ages >Python?, yo# %ay do this:
for file in files: f = open(file, 5r6) print frea"line()
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
29/76
Antipattern: Synchrono#s Code
/he Node.js e#ivalent is:
*ased on ea%ples 0ro%: https:&&gith#$.co%&node$its&distilled
var fs = require('fs');
for (var i = 1;i 2 files.length;i+ + ){ data = fs.rea"File-ync(files7i8); console.log(data);
}
Band it "ill ca#se severe per0or%ancepro$le%s
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
30/76
Pattern: Async &-
fs = require('fs');
fs.rea"File('f3t&t','!tf9',function(err,data){
if (err) {
// handle error
}
console.log(data);
});
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
31/76
Async &-
fs = require('fs');
fs.rea"File('f3t&t','!tf9',function(err,data){
if (err) {
// handle error
}
console.log(data);
});
Anony%o#s, inline call$ac)
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
32/76
Async &-
fs = require('fs');
fs.rea"File('f3t&t','!tf9',
function(err,data){
if (err) {
// handle error
}
console.log(data);
}
);
E#ivalent
synta
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
33/76
Call$ac) ell
8hen "or)ing "ith call$ac)s, nestingcan get #ite o#t o0 handB
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
34/76
Call$ac) ell
var db = require('som e"ataasepro$i"er');
%%get recent posts
http.get('recentposts', function(req, res) {
%% open ata!ase connection
db.open0onnection('host', creds,function(err, conn){ res.param 7'posts'8.forach(post) {
conn.
conn.close();
res.sen"(users718);
});
}
});
});
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
35/76
Call$ac) ell
var db = require('som e"ataasepro$i"er');
%%get recent posts
http.get('recentposts', function(req, res) {
%% open ata!ase connection
db.open0onnection('host', creds,function(err, conn){ res.param 7'posts'8.forach(post) {
conn.
conn.close();
res.sen"(users718);
});
}
});
});
et recent posts 0ro% "e$service AP
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
36/76
Call$ac) ell
var db = require('som e"ataasepro$i"er');
%%get recent posts
http.get('recentposts', function(req, res) {
%% open ata!ase connection
db.open0onnection('host', creds,function(err, conn){ res.param 7'posts'8.forach(post) {
conn.
conn.close();
res.sen"(users718);
});
}
});
});
-pen connection to D*
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
37/76
Call$ac) ell
var db = require('som e"ataasepro$i"er');
%%get recent posts
http.get('recentposts', function(req, res) {
%% open ata!ase connection
db.open0onnection('host', creds,function(err, conn){ res.param 7'posts'8.forach(post) {
conn.
conn.close();
res.sen"(users718);
});
}
});
});
et #ser 0ro% D* 0or eachpost
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
38/76
Call$ac) ell
var db = require('som e"ataasepro$i"er');
%%get recent posts
http.get('recentposts', function(req, res) {
%% open ata!ase connection
db.open0onnection('host', creds,function(err, conn){ res.param 7'posts'8.forach(post) {
conn.
conn.close();
res.sen"(users718);
});
}
});
});
et#rn #sers
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
39/76
Call$ac) ell
var db = require('som e"ataasepro$i"er');
%%get recent posts
http.get('recentposts', function(req, res) {
%% open ata!ase connection
db.open0onnection('host', creds,function(err, conn){ res.param 7'posts'8.forach(post) {
conn.
conn.close();
res.sen"(users718);
});
}
});
});
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
40/76
AntiPattern: Call$ac) ellfs.rea""ir(source, function(err, files) {
if (err) {
console.log('rror fin"ing files: ' + err)
} else {
files.forach(function(filename, fileIndex) {
console.log(filename)
gm(source + filename).si>e(function(err, values) {
if (err) {
console.log('rror i"entifying file si>e: ' + err)
} else { console.log(filename + ' : ' + values)
aspect = (values. i"th values.height)
widths.forach(function(width, widthIndex) {
height = Math.ro!n"(width aspect)
console.log('resi>ing ' + filename + 'to ' + height + '&' + height)
this.resi>e(width, height).write(destination+ ' 6+ width+ '?6+ filename, function(err){
if (err) console.log('rror riting file: ' + err)
}) }.in"(this))
}
})
})
}
})
http:&&call$ac)hell.co%&
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
41/76
Sol#tions
• Separate anony%o#s call$ac)0#nctions >cos%etic?
• Async.js
• Pro%ises
• enerators
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
42/76
Pattern:
Separate Call$ac)s
fs = require('fs');
callback = function(err,data){ if (err) {
// handle error
}
console.log(data); }
fs.rea"File('f3t&t','!tf9',callack);
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
43/76
Can /#rn /his
var db = require('som e"ataasepro$i"er');
http.get('recentposts', function(req, res){
db.open0onnection('host',creds,function(err, conn){
res.param 7'posts'8.forach(post) { conn.
post7'!ser'8,function(err,results){
conn.close();
res.sen"(results718);
});
}
});
});
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
44/76
nto /his
var db = require('som e"ataasepro$i"er');
http.get('recentposts', afterRecentPosts);
function afterRecentPosts(req, res) {
db.open0onnection('host', creds, function(err, conn) {
afterDBConnected(res, conn); });
}
function afterDBConnected(err, conn) {
res.param 7'posts'8.forach(post) {
conn.
} }
function afterQuery(err, results) {
conn.close();
res.sen"(results718);
}
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
45/76
/his is really a Control 'low iss#e
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
46/76
Pattern: Async.js
Async.js provides co%%on patterns 0orasync code control Go"
https:&&gith#$.co%&caolan&async
Also provides so%e co%%on 0#nctionalprogra%%ing paradig%s
https://github.com/caolan/asynchttps://github.com/caolan/asynchttps://github.com/caolan/async
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
47/76
Serial&Parallel F#nctions
• So%eti%es yo# have linearserial¶llel co%p#tations to r#n,"itho#t $ranching call$ac) gro"th
F#nction4
F#nction2
F#nction3
F#nction7
F#nction4
F#nction2
F#nction3
F#nction7
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
48/76
Serial&Parallel F#nctions
async.parallel(7
function(){ ... },
function(){ ... }
8, callback);
async.series(7
function(){ ... }, function(){ ... }
8);
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
49/76
Serial&Parallel F#nctions
async.parallel(7
function(){ ... },
function(){ ... }
8, callback);
async.series(7
function(){ ... }, function(){ ... }
8, callback);
Single Call$ac)
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
50/76
8ater0all
Async. aterfall(7
function(callack){ ... },
function(inp!t,callack){ ... },
function(inp!t,callack){ ... },
8, callback);
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
51/76
Map
var arr = 7'file3','file','file@'8;
async.m ap(arr, fs.stat, function(err, results){
%% results is an array of stats for each (le
console.log('File stats: ' +
JSON.stringify(results));
});
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
52/76
Filter
var arr = 7'file3','file','file@'8;
async.filter(arr, fs.e&ists, function(results){
%% results is a list of the e)isting (les
console.log('&isting files: ' + results);
});
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
53/76
8ith great po"erB
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
54/76
Care0ree
var fs = require('fs');
for (var i = 1; i 2 31111; i+ + ) {
fs.rea"File-ync(filename);
}
8ith synchrono#s code, yo# can loop as %#chas yo# "ant:
/he 1le is opened once each iteration.
/his "or)s, $#t is slo" and de0eats the point o0
Node.
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
55/76
Synchrono#s Doesn(t Scale
8hat i0 "e "ant to scale to 4H,HHHIconc#rrent #sers
File &-$eco%es the$ottlenec)
Users get in along line
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
56/76
Async to the esc#e
var fs = require('fs');
function onRead(err, file) { if (err) throw err;
}
for (var i = 1; i 2 31111; i+ + ) {
fs.rea"File(filename, onRead);
}
8hat happens i0 do this asyncrono#sly
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
57/76
#h oh
/he event loop is fast
/his "ill open the 1le 4H,HHH ti%es atonce
/his is #nnecessaryBand on %ostsyste%s, yo# "ill r#n o#t o0 1ledescriptors
P tt
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
58/76
Pattern:
/he e#est *atch
• -ne sol#tion is to $atch re#ests
• Piggy$ac) on eisting re#ests 0orthe sa%e 1le
• Each 1le then only has one openre#est at a ti%e, regardless o0
re#esting clients
// Batching wrapper for fs.readFile()
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
59/76
var requestBatches = {};
function batchedReadFile(filename, callback) {
// Is there already a batch for this file?
if (filename in requestBatches) {
// if so, push callback into batch
requestBatches[filename].push(callback);
return;
}
// If not, start a new request
var callbacks = requestBatches[filename] = [callback];
fs.readFile(filename, onRead);
// Flush out the batch on coplete
function onRead(err, file) {
delete requestBatches[filename];
for(var i = 0;i
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
60/76
var requestBatches = {};
function batchedReadFile(filename, callback) {
// Is there already a batch for this file?
if (filename in requestBatches) {
// if so, push callback into batch
requestBatches[filename].push(callback);
return;
}
// If not, start a new request
var callbacks = requestBatches[filename] = [callback];
fs.readFile(filename, onRead);
// Flush out the batch on coplete
function onRead(err, file) {
delete requestBatches[filename];
for(var i = 0;i
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
61/76
var requestBatches = {};
function batchedReadFile(filename, callback) {
// Is there already a batch for this file?
if (filename in requestBatches) {
// if so, push callback into batch
requestBatches[filename].push(callback);
return;
}
// If not, start a new request
var callbacks = requestBatches[filename] = [callback];
fs.readFile(filename, onRead);
// Flush out the batch on coplete
function onRead(err, file) {
delete requestBatches[filename];
for(var i = 0;i
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
62/76
var requestBatches = {};
function batchedReadFile(filename, callback) {
// Is there already a batch for this file?
if (filename in requestBatches) {
// if so, push callback into batch
requestBatches[filename].push(callback);
return;
}
// If not, start a new request
var callbacks = requestBatches[filename] = [callback];
fs.readFile(filename, onRead);
// Flush out the batch on coplete
function onRead(err, file) {
delete requestBatches[filename];
for(var i = 0;i
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
63/76
Usage
%%*e+uest the resource -,--- times at once
for (var i = 1; i 2 31111; i+ + ) {
batchedReadFile(file, onComplete);
}
function onComplete(err, file) {
if (err
) throw
err;else console.log('File contents: ' + file);
}
*ased on ea%ples 0ro%: https:&&gith#$.co%&node$its&distilled
Pattern
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
64/76
Pattern:
/he e#est *atch
/his pattern is e=ective on %any readtype operations, not j#st 1le reads
Ea%ple: also good 0or "e$ service APcalls
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
65/76
Shortco%ings
*atching re#ests is great 0or highre#est spi)es
-0ten, yo# are %ore li)ely to seesteady re#ests 0or the sa%e reso#rce
/his $egs 0or a caching sol#tion
Pattern:
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
66/76
Pattern:
e#est Cache
'et(s try a si%ple cache
Persist the res#lt 0orever and chec) 0orne" re#ests 0or sa%e reso#rce
%% Caching wrapper aroun fs#rea'ile./
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
67/76
var requestCache = {};
function cachingReadFile(filename, callback) {
%%Do we have resource in cache0
if (filename in requestCache) {
var value = requestCache7filename8;
%% 1sync !ehavior: elay result till ne)t tick
process.ne&t*ick(function () { callback(null, value); });
return;
}
%% If not, start a new re+uest
fs.rea"File(filename, onRead);
%% Cache the result if there is no error
function onRead(err, contents) {
if (%err) requestCache7filename8 = contents; callback(err, contents);
}
}
*ased on ea%ples 0ro%: https:&&gith#$.co%&node$its&distilled
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
68/76
Usage
%% *e+uest the (le -,--- times in series
%% 2ote: for serial re+uests we nee to iterate
%% with call!acks, rather than within a loop
var its = 31111; cachingReadFile(file, next);
function next(err, contents) {
console.log('File contents: ' + contents); if (%(itsAA)) return;
cachingReadFile(file, next);
}
*ased on ea%ples 0ro%: https:&&gith#$.co%&node$its&distilled
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
69/76
Al%ost /here
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
70/76
var requestBatches = {}, requestCache = {};
function readFile(filename, callback) {
if (filename in requestCache) { %% Do we have resource in cache0
var value = requestCache7filename8;
%% Delay result till ne)t tick to act async process.ne&t*ick(function () { callback(null, value); });
return;
}
if (filename in requestBatches) { %% Else, oes (le have a !atch0
requestBatches7filename8.p!sh(callback);
return; }
%% If neither, create new !atch an re+uest
var callbacks = requestBatches7filename8 = 7callback8;
fs.rea"File(filename, onRead);
%% Cache the result an "ush !atch
function onRead(err, file) { if (%err) requestCache7filename8 = file;
delete requestBatches7filename8;
for (var i= 1;i2 callbacks.length;i+ + ) { callbacks7i8(err, file); }
}
}
*ased on ea%ples 0ro%: https:&&gith#$.co%&node$its&distilled
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
71/76
scale0s
"rote a %od#le 0or scala$le File &-
https:&&""".np%js.org&pac)age&scale0s
Usage:
var fs = require(6scaleAfs');
for (var i = 1; i 2 31111; i+ + ) {
fs.rea"File(filename);
}
https://www.npmjs.org/package/scale-fshttps://www.npmjs.org/package/scale-fshttps://www.npmjs.org/package/scale-fshttps://www.npmjs.org/package/scale-fs
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
72/76
Final /ho#ghts
Most antipatterns in Node.js co%e 0ro%:
•
S)etchy +avaScript heritage• neperience "ith Asynchrono#s /hin)ing
e%e%$er, let the Event 'oop do theheavy li0ting
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
73/76
/han)s
Code sa%ples 0ro% this tal) at:
https:&&gith#$.co%&cacois&nodepatternsdiscerning
https://github.com/cacois/node-patterns-discerninghttps://github.com/cacois/node-patterns-discerninghttps://github.com/cacois/node-patterns-discerninghttps://github.com/cacois/node-patterns-discerning
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
74/76
Disclai%er
/ho#gh a% an e%ployee o0 theSo0t"are Engineering nstit#te atCarnegie Mellon University, this "o)
"as not 0#nded $y the SE and doesnot reGect the "or) or opinions o0 theSE or its c#sto%ers.
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
75/76
'et(s chat
!aaroncois
""".codehenge.net
gith#$.co%&cacois
/he event loop e@ciently
Node apps pass asynctas)s to the event
1 2
-
8/15/2019 Nodejs Design Patterns 130602183400 Phpapp02
76/76
Node.jsEvent
'oop
%anages a thread pool andeec#tes tas)s e@cientlyB
/hread4
/hread2
/hreadn
B /as) 4
/as) 2
/as) 3
/as) 7
et#rn 4
Call$ac)4>?
d t h
Node.jsapp
tas)s to the eventloop, along "ith acall$ac)
>0#nction, call$ac)?
1 2