SlideShare a Scribd company logo
CH 5. 제어 흐름, 비동기 패턴,
예외 처리
Learning Node
김지훈
Promise
Node의 초기 비동기 구현
success와 error 두 개의 이벤트만 가짐
Promise
var File = require('file');
var promise = File.read('mydata.txt');
promise.addCallback(function (data) {
// process data
});
promise.addErrback(function (err) {
// deal with error
})
– Ryan Dahl -
‘promise대신 최종 인수 콜백을 사용하도록 하고, 보다
나은 추상화 계층을 구축하는 것은 사용자 라이브러리에
맡기도록 하겠다.’
Promise 의 제거
Node 0.1.30
최종 인수 콜백
모든 비동기 메서드는 마지막 인수로 콜백 함수를 받음
콜백의 첫번째 인수는 항상 error 개체
Last Argument Callbacks
최종 인수 콜백 구현 예시
var obj = function() { };	

obj.prototype.doSomething = function(arg1, arg2_) {
var arg2 = typeof(arg2_) === 'string' ? arg2_ : null;	

	

 var callback_ = arguments[arguments.length - 1];

	

 callback = (typeof(callback_) == 'function' ? callback_ : null);	

if (!arg2)	

	

 	

 return callback(new Error('second argument missing or not string')); 	

 	

 	

	

 callback(arg1);	

}

var test = new obj();

test.doSomething(‘test', ‘this’, function(err,value) {	

	

 if (err) throw err;	

	

 console.log(value);
});
최종 인수 콜백의 역할
마지막 인수가 함수임을 보증
오류가 발생한 경우 Node Error를 생성하여 반환
오류가 발생하지 않으면 메서드의 결과를 전달하여 콜백 호출
중첩 콜백
!
var fs = require('fs');	

try {

fs.readFile('./apples2.txt','utf8', function(err,data) {	

	

 	

 if (err) throw err;

var adjData = data.replace(/[A|a]pple/g,'orange');
fs.writeFile('./oranges.txt', adjData,function(err) {	

	

 	

 	

 if (err) throw err
});	

	

 });

} catch(err) {	

	

 console.error(err);
}
Nested Callbacks
// get list of files

fs.readdir('./data/', function(err, files) {	

	

 // for each file
files.forEach(function(name) {	

	

// modify contents

fs.readFile('./data/' + name,'utf8', function(err,data) {	

	

 	

 	

 if (err) throw err;

var adjData = data.replace(/somecompany.com/g,'burningbird.net');	

	

 	

 	

 // write to file

fs.writeFile('./data/' + name, adjData, function(err) {	

	

 	

 	

 	

 if (err) throw err;	

	

 	

 	

 	

 // log write

writeStream.write('changed ' + name + 'n', 'utf8', function(err) {	

	

 	

 	

 	

 	

 if(err) throw err;
});	

	

 	

 	

 });
});	

	

 });
});	

콜백 스파게티, 죽음의 피라미드
(Pyramid of Doom)
changed data1.txt
changed data3.txt
changed data5.txt
changed data2.txt
changed data4.txt
!
changed data3.txt
changed data1.txt
changed data5.txt
changed data2.txt
changed data4.txt
!
changed data1.txt
changed data3.txt
changed data5.txt
changed data4.txt
changed data2.txt
콜백이 호출되는 순서도 무작위
서드파티 모듈
Node는 기본적인 콜백 기능만 제공
보다 높은 추상화는 서드파티 모듈에 의존해야 함
Step, Async
Step
간단한 서드파티 비동기 모듈
실행할 함수 리스트를 넘겨주면 순차적으로 실행해줌
var fs = require('fs'), Step = require('step');	

try {	

	

 Step (
function readData() { // 비동기 함수	

	

 	

 	

 fs.readFile('./data/data1.txt', 'utf8', this);
},	

	

 	

 function modify(err, text) { // 동기 함수
if (err) throw err;
return text.replace(/somecompany.com/g,'burningbird.net');	

	

 	

 },
function writeData(err, text) { // 비동기 함수	

	

 	

 	

 if (err) throw err;	

	

 	

 	

 fs.writeFile('./data/data1.txt', text, this);
}	

	

 );
} catch(err) {	

	

 console.error(err);
}
콜백 대신에 this를 전달
첫 번째 함수를 제외한 모든 함수는 첫 번째 매개변수로 error를 요구
에러는 예외로 처리
…생략… 	

try {	

Step (
function readDir() {	

	

 	

 fs.readdir(_dir, this);
},	

	

 function readFile(err, results) {
if (err) throw err;
files = results;
var group = this.group();
results.forEach(function(name) {	

	

 	

 	

 fs.readFile(_dir + name, 'utf8', group());	

	

 	

 });
},	

	

 function writeAll(err, data) {
if (err) throw err;
for (var i = 0; i < files.length; i++) {	

	

 	

 	

 var adjdata = data[i].replace(/somecompany.com/g,'burningbird.net');	

	

 	

 	

 fs.writeFile(_dir + files[i], adjdata, 'utf8',this);
}	

	

 } );	

} catch(err) {
console.log(err);	

}
! 결과가 배열로 그룹화 되어 전달됨
병렬로 실행하기
var fs = require('fs'), Step = require('step'), files;	

try {	

	

 Step (
function readFiles() {	

	

 	

 	

 fs.readFile('./data/data1.txt', 'utf8',this.parallel());
fs.readFile('./data/data2.txt', 'utf8',this.parallel());
fs.readFile('./data/data3.txt', 'utf8',this.parallel());	

	

 	

 },
function writeFiles(err, data1, data2, data3) {	

	

 	

 	

 if (err) throw err;
data1 = data1.replace(/somecompany.com/g,'burningbird.net');
data2 = data2.replace(/somecompany.com/g,'burningbird.net');
data3 = data3.replace(/somecompany.com/g,'burningbird.net');	

	

 	

 	

 fs.writeFile('./data/data1.txt', data1, 'utf8',this.parallel());
fs.writeFile('./data/data2.txt', data2, 'utf8', this.parallel());
fs.writeFile('./data/data3.txt', data3, 'utf8', this.parallel());	

	

 	

 } );	

} catch(err) {
console.log(err);	

}
this.parallel()이 각 함수의 순서를 보장
Async
더 다양한 기능을 제공
기존 콜백구조와 매우 유사한 코드 스타일
var fs = require('fs'), async = require('async');	

try {
async.waterfall([	

	

 	

 function readData(callback) {
fs.readFile('./data/data1.txt', 'utf8', function(err, data){	

	

 	

 	

 	

 callback(err,data);
});	

	

 	

 },
function modify(text, callback) {	

	

 	

 	

 var adjdata=text.replace(/somecompany.com/g,'burningbird.net');	

	

 	

 	

 callback(null, adjdata);
},	

	

 	

 function writeData(text, callback) {
fs.writeFile('./data/data1.txt', text, function(err) {	

	

 	

 	

 	

 callback(err,text);
});	

	

 	

 }
], function (err, result) {//에러 발생시 처리를 중단하고 완료 콜백 호출	

	

 	

 if (err) throw err;	

	

 	

 console.log(result);
});	

} catch(err) {
console.log(err);	

}
async.waterfall
……
function readData(stats, file, callback) {
if (stats.isFile())	

	

 fs.readFile(_dir + file, 'utf8', function(err, data){	

	

 	

 callback(err,file,data);
});	

},
function modify(file, text, callback) {	

	

 var adjdata=text.replace(/somecompany.com/g,'burningbird.net');	

	

 callback(null, file, adjdata);
},
……
async.waterfall([작업 함수 배열, …], 완료 콜백);
파라메터 전달 흐름
callback의 첫번째 인자는 error개체, 각 함수의 마지막 인자는 callback개체
async.parallel
async.parallel({
작업 이름 : 작업 함수,
… 반복 …
}, 완료 콜백);
넘겨준 작업 함수들을 모두 동시에 실행
모든 함수의 동작이 끝나길 기다렸다가 완료 콜백 호출
var fs = require('fs'), async = require('async');!
try { !
! async.parallel({!
! ! data1 : function (callback) {!
! ! ! fs.readFile('./data/data1.txt', 'utf8', function(err, data){!
! ! ! ! callback(err,data); !
! ! ! });!
! ! },

! ! data2 : function (callback) {!
! ! ! fs.readFile('./data/data2.txt', 'utf8', function(err, data){ !
! ! ! ! callback(err,data);!
! ! ! });!
! ! },!
! ! data3 : function readData3(callback) { !
! ! ! fs.readFile('./data/data3.txt', 'utf8', function(err, data){!
! ! ! ! callback(err,data); !
! ! ! });!
! ! },!
! }, function (err, result) { // 완료 콜백!
! ! if (err) throw err;!
! ! console.log(result); !
! });!
} catch(err) {!
! console.log(err); !
}
입력
data1.txt : apple
data2.txt : oranges
data3.txt : peaches
!
결과
{ data1: ‘applesn’, data2: 'orangesn', data3: 'peachesn' }
{ 작업명 : 각 작업별 결과, … }
Node 스타일
동기보다는 비동기 함수를 사용
2칸 들여쓰기 사용
세미콜론을 사용 / 사용하지 마라
작은 따옴표를 사용
여러 변수 선언시 단일 var 키워드 사용 / 여러 var 키워드 사용
상수는 모두 대문자
변수는 camel case
완전 항등 연산자(===) 사용
함수에 이름 붙이기
라인길이 80자 이하
중괄호는 중괄호를 필요로 하는 것과 같은 줄에서 시작

More Related Content

PPTX
골때리는 자바스크립트 발표자료
PPTX
Startup JavaScript 8 - NPM, Express.JS
PPTX
Startup JavaScript 5 - 객체(Date, RegExp, Object, Global)
PDF
비전공자의 자바스크립트 도전기
PDF
7가지 동시성 모델 4장
PPTX
Startup JavaScript 6 - 함수, 스코프, 클로저
PPT
헷갈리는 자바스크립트 정리
PDF
함수적 사고 2장
골때리는 자바스크립트 발표자료
Startup JavaScript 8 - NPM, Express.JS
Startup JavaScript 5 - 객체(Date, RegExp, Object, Global)
비전공자의 자바스크립트 도전기
7가지 동시성 모델 4장
Startup JavaScript 6 - 함수, 스코프, 클로저
헷갈리는 자바스크립트 정리
함수적 사고 2장

What's hot (20)

PPTX
Javascript 실행 가능한 코드(Executable Code)와 실행 콘텍스트(Execution Context), Lexical En...
PPTX
7가지 동시성 모델 - 3장. 함수형 프로그래밍
PPTX
Startup JavaScript 4 - 객체
PPTX
프론트엔드스터디 E05 js closure oop
PPTX
[하코사 세미나] 비전공자의 자바스크립트 도전기
PPTX
Jupyter notebok tensorboard 실행하기_20160706
PPTX
Javascript 함수(function) 개념, 호출패턴, this, prototype, scope
PDF
7가지 동시성 모델 - 데이터 병렬성
PPTX
Startup JavaScript 3 - 조건문, 반복문, 예외처리
PPTX
[Gpg2권 박민근] 1.13 스택 와인딩
PDF
Javascript 교육자료 pdf
PDF
파이썬 데이터베이스 연결 2탄
PPTX
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍
PDF
[Swift] Protocol (2/2)
PDF
파이썬 데이터베이스 연결 1탄
PDF
파이썬 웹프로그래밍 1탄
PDF
[D2 COMMUNITY] ECMAScript 2015 S67 seminar - 1. primitive
PDF
Ji 개발 리뷰 (신림프로그래머)
PPTX
프론트엔드스터디 E04 js function
PPTX
[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로
Javascript 실행 가능한 코드(Executable Code)와 실행 콘텍스트(Execution Context), Lexical En...
7가지 동시성 모델 - 3장. 함수형 프로그래밍
Startup JavaScript 4 - 객체
프론트엔드스터디 E05 js closure oop
[하코사 세미나] 비전공자의 자바스크립트 도전기
Jupyter notebok tensorboard 실행하기_20160706
Javascript 함수(function) 개념, 호출패턴, this, prototype, scope
7가지 동시성 모델 - 데이터 병렬성
Startup JavaScript 3 - 조건문, 반복문, 예외처리
[Gpg2권 박민근] 1.13 스택 와인딩
Javascript 교육자료 pdf
파이썬 데이터베이스 연결 2탄
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍
[Swift] Protocol (2/2)
파이썬 데이터베이스 연결 1탄
파이썬 웹프로그래밍 1탄
[D2 COMMUNITY] ECMAScript 2015 S67 seminar - 1. primitive
Ji 개발 리뷰 (신림프로그래머)
프론트엔드스터디 E04 js function
[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로
Ad

Similar to Learning Node Book, Chapter 5 (20)

PPTX
Promise 패턴 공부
PPTX
소셜게임 서버 개발 관점에서 본 Node.js의 장단점과 대안
PDF
Javascript 조금 더 잘 알기
PDF
Node.js 팀 스터디 발표자료.
PPTX
Node week1
PDF
Node.js 현재와 미래
PDF
ES6 for Node.js Study 4주차
PDF
Node.js intro
PDF
Nodejs_chapter3
PPTX
7가지 동시성 모델 - 6장. 순차 프로세스 통신
PDF
Nodejs발표자료 - 팀 세미나용
PDF
Node.js 기본
PPTX
javascript03
PPTX
Node.js의 도입과 활용
PDF
Node.js at OKJSP
PDF
Node.js 첫걸음
PDF
Promise and Bluebird
PDF
진짜기초 Node.js
PDF
JavaScript Promises
PDF
Node.js 시작하기
Promise 패턴 공부
소셜게임 서버 개발 관점에서 본 Node.js의 장단점과 대안
Javascript 조금 더 잘 알기
Node.js 팀 스터디 발표자료.
Node week1
Node.js 현재와 미래
ES6 for Node.js Study 4주차
Node.js intro
Nodejs_chapter3
7가지 동시성 모델 - 6장. 순차 프로세스 통신
Nodejs발표자료 - 팀 세미나용
Node.js 기본
javascript03
Node.js의 도입과 활용
Node.js at OKJSP
Node.js 첫걸음
Promise and Bluebird
진짜기초 Node.js
JavaScript Promises
Node.js 시작하기
Ad

More from Ji Hun Kim (11)

PDF
Doing data science Chapter 9
PDF
Ninja
PDF
Arduino 소개, RC카 만들기
PDF
High performance networking in chrome
PDF
Api design for c++ 6장
PDF
Windbg랑 친해지기
PPTX
Code 25장
PPTX
Code 17장
PPTX
Code 10장
PPTX
Python packaging
PPTX
읽기 좋은 코드가 좋은 코드다 Part one
Doing data science Chapter 9
Ninja
Arduino 소개, RC카 만들기
High performance networking in chrome
Api design for c++ 6장
Windbg랑 친해지기
Code 25장
Code 17장
Code 10장
Python packaging
읽기 좋은 코드가 좋은 코드다 Part one

Learning Node Book, Chapter 5

  • 1. CH 5. 제어 흐름, 비동기 패턴, 예외 처리 Learning Node 김지훈
  • 2. Promise Node의 초기 비동기 구현 success와 error 두 개의 이벤트만 가짐
  • 3. Promise var File = require('file'); var promise = File.read('mydata.txt'); promise.addCallback(function (data) { // process data }); promise.addErrback(function (err) { // deal with error })
  • 4. – Ryan Dahl - ‘promise대신 최종 인수 콜백을 사용하도록 하고, 보다 나은 추상화 계층을 구축하는 것은 사용자 라이브러리에 맡기도록 하겠다.’ Promise 의 제거 Node 0.1.30
  • 5. 최종 인수 콜백 모든 비동기 메서드는 마지막 인수로 콜백 함수를 받음 콜백의 첫번째 인수는 항상 error 개체 Last Argument Callbacks
  • 6. 최종 인수 콜백 구현 예시 var obj = function() { }; obj.prototype.doSomething = function(arg1, arg2_) { var arg2 = typeof(arg2_) === 'string' ? arg2_ : null; var callback_ = arguments[arguments.length - 1];
 callback = (typeof(callback_) == 'function' ? callback_ : null); if (!arg2) return callback(new Error('second argument missing or not string')); callback(arg1); }
 var test = new obj();
 test.doSomething(‘test', ‘this’, function(err,value) { if (err) throw err; console.log(value); });
  • 7. 최종 인수 콜백의 역할 마지막 인수가 함수임을 보증 오류가 발생한 경우 Node Error를 생성하여 반환 오류가 발생하지 않으면 메서드의 결과를 전달하여 콜백 호출
  • 8. 중첩 콜백 ! var fs = require('fs'); try {
 fs.readFile('./apples2.txt','utf8', function(err,data) { if (err) throw err;
 var adjData = data.replace(/[A|a]pple/g,'orange'); fs.writeFile('./oranges.txt', adjData,function(err) { if (err) throw err }); });
 } catch(err) { console.error(err); } Nested Callbacks
  • 9. // get list of files
 fs.readdir('./data/', function(err, files) { // for each file files.forEach(function(name) { // modify contents
 fs.readFile('./data/' + name,'utf8', function(err,data) { if (err) throw err;
 var adjData = data.replace(/somecompany.com/g,'burningbird.net'); // write to file
 fs.writeFile('./data/' + name, adjData, function(err) { if (err) throw err; // log write
 writeStream.write('changed ' + name + 'n', 'utf8', function(err) { if(err) throw err; }); }); }); }); }); 콜백 스파게티, 죽음의 피라미드 (Pyramid of Doom)
  • 10. changed data1.txt changed data3.txt changed data5.txt changed data2.txt changed data4.txt ! changed data3.txt changed data1.txt changed data5.txt changed data2.txt changed data4.txt ! changed data1.txt changed data3.txt changed data5.txt changed data4.txt changed data2.txt 콜백이 호출되는 순서도 무작위
  • 11. 서드파티 모듈 Node는 기본적인 콜백 기능만 제공 보다 높은 추상화는 서드파티 모듈에 의존해야 함 Step, Async
  • 12. Step 간단한 서드파티 비동기 모듈 실행할 함수 리스트를 넘겨주면 순차적으로 실행해줌
  • 13. var fs = require('fs'), Step = require('step'); try { Step ( function readData() { // 비동기 함수 fs.readFile('./data/data1.txt', 'utf8', this); }, function modify(err, text) { // 동기 함수 if (err) throw err; return text.replace(/somecompany.com/g,'burningbird.net'); }, function writeData(err, text) { // 비동기 함수 if (err) throw err; fs.writeFile('./data/data1.txt', text, this); } ); } catch(err) { console.error(err); } 콜백 대신에 this를 전달 첫 번째 함수를 제외한 모든 함수는 첫 번째 매개변수로 error를 요구 에러는 예외로 처리
  • 14. …생략… try { Step ( function readDir() { fs.readdir(_dir, this); }, function readFile(err, results) { if (err) throw err; files = results; var group = this.group(); results.forEach(function(name) { fs.readFile(_dir + name, 'utf8', group()); }); }, function writeAll(err, data) { if (err) throw err; for (var i = 0; i < files.length; i++) { var adjdata = data[i].replace(/somecompany.com/g,'burningbird.net'); fs.writeFile(_dir + files[i], adjdata, 'utf8',this); } } ); } catch(err) { console.log(err); } ! 결과가 배열로 그룹화 되어 전달됨
  • 15. 병렬로 실행하기 var fs = require('fs'), Step = require('step'), files; try { Step ( function readFiles() { fs.readFile('./data/data1.txt', 'utf8',this.parallel()); fs.readFile('./data/data2.txt', 'utf8',this.parallel()); fs.readFile('./data/data3.txt', 'utf8',this.parallel()); }, function writeFiles(err, data1, data2, data3) { if (err) throw err; data1 = data1.replace(/somecompany.com/g,'burningbird.net'); data2 = data2.replace(/somecompany.com/g,'burningbird.net'); data3 = data3.replace(/somecompany.com/g,'burningbird.net'); fs.writeFile('./data/data1.txt', data1, 'utf8',this.parallel()); fs.writeFile('./data/data2.txt', data2, 'utf8', this.parallel()); fs.writeFile('./data/data3.txt', data3, 'utf8', this.parallel()); } ); } catch(err) { console.log(err); } this.parallel()이 각 함수의 순서를 보장
  • 16. Async 더 다양한 기능을 제공 기존 콜백구조와 매우 유사한 코드 스타일
  • 17. var fs = require('fs'), async = require('async'); try { async.waterfall([ function readData(callback) { fs.readFile('./data/data1.txt', 'utf8', function(err, data){ callback(err,data); }); }, function modify(text, callback) { var adjdata=text.replace(/somecompany.com/g,'burningbird.net'); callback(null, adjdata); }, function writeData(text, callback) { fs.writeFile('./data/data1.txt', text, function(err) { callback(err,text); }); } ], function (err, result) {//에러 발생시 처리를 중단하고 완료 콜백 호출 if (err) throw err; console.log(result); }); } catch(err) { console.log(err); }
  • 18. async.waterfall …… function readData(stats, file, callback) { if (stats.isFile()) fs.readFile(_dir + file, 'utf8', function(err, data){ callback(err,file,data); }); }, function modify(file, text, callback) { var adjdata=text.replace(/somecompany.com/g,'burningbird.net'); callback(null, file, adjdata); }, …… async.waterfall([작업 함수 배열, …], 완료 콜백); 파라메터 전달 흐름 callback의 첫번째 인자는 error개체, 각 함수의 마지막 인자는 callback개체
  • 19. async.parallel async.parallel({ 작업 이름 : 작업 함수, … 반복 … }, 완료 콜백); 넘겨준 작업 함수들을 모두 동시에 실행 모든 함수의 동작이 끝나길 기다렸다가 완료 콜백 호출
  • 20. var fs = require('fs'), async = require('async');! try { ! ! async.parallel({! ! ! data1 : function (callback) {! ! ! ! fs.readFile('./data/data1.txt', 'utf8', function(err, data){! ! ! ! ! callback(err,data); ! ! ! ! });! ! ! },
 ! ! data2 : function (callback) {! ! ! ! fs.readFile('./data/data2.txt', 'utf8', function(err, data){ ! ! ! ! ! callback(err,data);! ! ! ! });! ! ! },! ! ! data3 : function readData3(callback) { ! ! ! ! fs.readFile('./data/data3.txt', 'utf8', function(err, data){! ! ! ! ! callback(err,data); ! ! ! ! });! ! ! },! ! }, function (err, result) { // 완료 콜백! ! ! if (err) throw err;! ! ! console.log(result); ! ! });! } catch(err) {! ! console.log(err); ! }
  • 21. 입력 data1.txt : apple data2.txt : oranges data3.txt : peaches ! 결과 { data1: ‘applesn’, data2: 'orangesn', data3: 'peachesn' } { 작업명 : 각 작업별 결과, … }
  • 22. Node 스타일 동기보다는 비동기 함수를 사용 2칸 들여쓰기 사용 세미콜론을 사용 / 사용하지 마라 작은 따옴표를 사용 여러 변수 선언시 단일 var 키워드 사용 / 여러 var 키워드 사용 상수는 모두 대문자 변수는 camel case 완전 항등 연산자(===) 사용 함수에 이름 붙이기 라인길이 80자 이하 중괄호는 중괄호를 필요로 하는 것과 같은 줄에서 시작