Upload
iamhjoo-
View
15.901
Download
3
Embed Size (px)
DESCRIPTION
Node.js에 주요 이슈 중 하나인 Flow Control에 대해서 Octobersky.js 모임에서 발표한 자료
Citation preview
Flow Control in Node.js송형주
● 삼성전자 소프트웨어센터 Web Convergence Lab.
● 블로그
Inside.JS (http://www.nodejs-kr.org/insidejs)
Profile
var fs = require('fs') , path = './sync.txt'; var stats = fs.statSync(path);
if (stats == undefined) { // read the contents of this file var content = fs.readFileSync(__filename);} var code = content.toString();// write the content to sync.txtvar err = fs.writeFileSync(path, code);if(err) throw err;console.log('sync.txt created!'); console.log(‘Another Task’);
Synchronous Programming
var fs = require('fs') , path = './async.txt'; // check if async.txt existsfs.stat(path, function(err, stats) { if (stats == undefined) { // read the contents of this file fs.readFile(__filename, function(err, content) { var code = content.toString(); // write the content to async.txt fs.writeFile(path, code, function(err) { if (err) throw err; console.log('async.txt created!'); }); }); }}); console.log(‘Another Task’);
Asynchronous Programming
Node.js programming is not easy.var open = false; setTimeout(function () { open = true;}, 1000); while(!open) { // wait} console.log('opened!');
Nested Callback Problemasync1(function(input, result1) { async2(function(result2) { async3(function(result3) { async4(function(result4) { async5(function(output) { // do something with output }); }); }); });})
Flow Control Problem
for(var i = 1; i <= 1000; i++) { fs.readFile('./'+i+'.txt',
function() { // do something with the file } );} do_next_part();
Why Flow Control?
• Asynchronous Programming • Issues – Doing a bunch of things in a specific order – Knowing when task is done. – Nested Callback – Collecting result data
Flow Control Pattern
• Serial Execution• Parallel Execution• Limited Parallel Execution
Serial Execution
Start
Task1
Task3
Continue when tasks complete
Task2
Parallel Execution
Start
Task1 Task3
Continue When tasks complete
Task2
Flow Control Libraries
• Async – providing various control function• Step – simple and easy to use• Slide – used in the npm client code• Seq• Nue• …
Node.js Coding Conventions• Two kinds of functions : – Action Function : Take action – Callback Function : Get results • Action functions – last argument is always a callback function
• Callback functions – first argument is always an error or null.
Action Function
CallbackFunctionResult
(Action Function Developer) (Action Function User)
Action Function Example
function actor (some, args, cb) { // last argument is callback // optional args: if (!cb && typeof(args) === "function")
cb = args, args = []; // do something, and then: if (failed) cb(new Error("failed!")) else cb(null, optionalData)}
Action Function
CallbackFunctionResult
Action Function과 Callback Function 사이는 결과를 어떻게 넘길 지에 대한 인터페이스가 명확히 규정되어 한다.
Action Function Example// return true if a path is either// a symlink or a directory. function isLinkOrDir (path, cb) { fs.lstat(path, function (er, s) { if (er) return cb(er); return cb(null, s.isDirectory() || s.isSymbolicLink()); });} isLinkorDir
cbResultfs.lstat _cb
er, s er, result
Usecases : Parallel Execution
● I have a list of 10 files, and need to read all of them, and then continue when they're all done.
● I have a dozen URLs, and need to fetch them all, and then continue when they're all done.
●I have 4 connected users, and need to send a message to all of them, and then continue when that's done.
function asyncMap (list, fn, cb_) { var n = list.length , results = [] , errState = null; function cb (er, data) { if (errState) return; if (er) return cb(errState = er); results.push(data); if (--n === 0) // 모든 리스트 처리 완료시
return cb_(null, results); } // action code list.forEach(function (l) { fn(l, cb); });}
asyncMap
listresult
fn cb
cb_
err, result
중간 결과 저장
err, data
Usecases : AsyncMapfunction writeFiles (files, what, cb) { asyncMap(files, function (f, cb_) { fs.writeFile(f,what,cb_); }, cb );} writeFiles([my,file,list], "foo", cb);
writeFiles
cb
err
asyncMap
files
cb_는 asyncMap의 내부 함수임
list
fn cb_
This implementation is fine if order doesn'tmatter, but what if it does?
function asyncMap(list, fn, cb_) { var n = list.length , results = [] , errState = null;
function cbGen (i) { return function cb(er, data) { if (errState) return; if (er) return cb(errState = er); results[i] = data; if (-- n === 0) return cb_(null, results); } } list.forEach(function (l, i) { fn(l, cbGen(i)); });}
usecase: Serial Execution
• I have to do a bunch of things, in order. Get db credentials out of a file, read the datafrom the db, write that data to another file. • If anything fails, do not continue.
function chain (things, cb) { (function LOOP (i, len) { if (i >= len) return cb(); things[i](function (er) { if (er) return cb(er); LOOP(i + 1, len) }) })(0, things.length)}
cb
chainLOOP,0
things[1]
LOOP, 3
things[0] LOOP,1
LOOP,2
things[2]
things
var fs = require('fs');var async = require('async'); var path = './async.txt';async.waterfall([
// check if async.txt existsfunction(cb) {
fs.stat(path, function(err, stats) { if (stats == undefined) cb(null); else console.log('async.txt exists'); });
},// read the contents of this filefunction(cb) {
fs.readFile(__filename, function(err, content) { var code = content.toString(); cb(null, code); });
},// write the content to async.txtfunction(code, cb) {
fs.writeFile(path, code, function(err) { if (err) throw err; console.log('async.txt created!'); });
}]);
Async Module Example
Step( function readSelf() { fs.readFile(__filename, 'utf8', this); }, function capitalize(err, text) { if (err) throw err; return text.toUpperCase(); }, function showIt(err, newText) { if (err) throw err; console.log(newText); });
Step Module Example
Step( // Loads two files in parallel function loadStuff() { fs.readFile(__filename, this.parallel()); fs.readFile("/etc/passwd", this.parallel()); }, // Show the result when done function showStuff(err, code, users) { if (err) throw err; console.log(code); console.log(users); })
Step Module Example
Reference
● slide module guide (Issacs) https://github.com/isaacs/slide-flow-control/blob/master/nodejs-controlling-flow.pdf