SlideShare a Scribd company logo
1 of 22
Download to read offline
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

What's hot

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

What's hot (20)

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

Similar to Learning Node Book, Chapter 5

EcmaScript6(2015) Overview
EcmaScript6(2015) OverviewEcmaScript6(2015) Overview
EcmaScript6(2015) Overviewyongwoo Jeon
 
읽기 좋은 코드가 좋은 코드다 Part one
읽기 좋은 코드가 좋은 코드다   Part one읽기 좋은 코드가 좋은 코드다   Part one
읽기 좋은 코드가 좋은 코드다 Part oneJi Hun Kim
 
Nodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjsNodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjs기동 이
 
Es2015 Simple Overview
Es2015 Simple OverviewEs2015 Simple Overview
Es2015 Simple OverviewKim Hunmin
 
스칼라와 스파크 영혼의 듀오
스칼라와 스파크 영혼의 듀오스칼라와 스파크 영혼의 듀오
스칼라와 스파크 영혼의 듀오Taeoh Kim
 
[JS] Function.prototype.bind
[JS] Function.prototype.bind[JS] Function.prototype.bind
[JS] Function.prototype.bindJinhyuck Kim
 
Perl Script Document
Perl Script DocumentPerl Script Document
Perl Script Document오석 한
 
파이썬+함수이해하기 20160229
파이썬+함수이해하기 20160229파이썬+함수이해하기 20160229
파이썬+함수이해하기 20160229Yong Joon Moon
 
Javascript개발자의 눈으로 python 들여다보기
Javascript개발자의 눈으로 python 들여다보기Javascript개발자의 눈으로 python 들여다보기
Javascript개발자의 눈으로 python 들여다보기지수 윤
 
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)Sang Don Kim
 
[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기
[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기
[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기Chris Ohk
 
Javascript 조금 더 잘 알기
Javascript 조금 더 잘 알기Javascript 조금 더 잘 알기
Javascript 조금 더 잘 알기jongho jeong
 
자바스크립트 함수
자바스크립트 함수자바스크립트 함수
자바스크립트 함수유진 변
 
10장 문자열 클래스와 파일 클래스
10장 문자열 클래스와 파일 클래스10장 문자열 클래스와 파일 클래스
10장 문자열 클래스와 파일 클래스유석 남
 

Similar to Learning Node Book, Chapter 5 (20)

EcmaScript6(2015) Overview
EcmaScript6(2015) OverviewEcmaScript6(2015) Overview
EcmaScript6(2015) Overview
 
읽기 좋은 코드가 좋은 코드다 Part one
읽기 좋은 코드가 좋은 코드다   Part one읽기 좋은 코드가 좋은 코드다   Part one
읽기 좋은 코드가 좋은 코드다 Part one
 
Javascript
JavascriptJavascript
Javascript
 
자바스크립트 클래스의 프로토타입(prototype of class)
자바스크립트 클래스의  프로토타입(prototype of class)자바스크립트 클래스의  프로토타입(prototype of class)
자바스크립트 클래스의 프로토타입(prototype of class)
 
Nodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjsNodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjs
 
Es2015 Simple Overview
Es2015 Simple OverviewEs2015 Simple Overview
Es2015 Simple Overview
 
스칼라와 스파크 영혼의 듀오
스칼라와 스파크 영혼의 듀오스칼라와 스파크 영혼의 듀오
스칼라와 스파크 영혼의 듀오
 
06장 함수
06장 함수06장 함수
06장 함수
 
[JS] Function.prototype.bind
[JS] Function.prototype.bind[JS] Function.prototype.bind
[JS] Function.prototype.bind
 
Perl Script Document
Perl Script DocumentPerl Script Document
Perl Script Document
 
파이썬+함수이해하기 20160229
파이썬+함수이해하기 20160229파이썬+함수이해하기 20160229
파이썬+함수이해하기 20160229
 
Javascript개발자의 눈으로 python 들여다보기
Javascript개발자의 눈으로 python 들여다보기Javascript개발자의 눈으로 python 들여다보기
Javascript개발자의 눈으로 python 들여다보기
 
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
 
[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기
[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기
[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기
 
Javascript 조금 더 잘 알기
Javascript 조금 더 잘 알기Javascript 조금 더 잘 알기
Javascript 조금 더 잘 알기
 
자바스크립트 함수
자바스크립트 함수자바스크립트 함수
자바스크립트 함수
 
Apache avro
Apache avroApache avro
Apache avro
 
Xe hack
Xe hackXe hack
Xe hack
 
JDK 변천사
JDK 변천사JDK 변천사
JDK 변천사
 
10장 문자열 클래스와 파일 클래스
10장 문자열 클래스와 파일 클래스10장 문자열 클래스와 파일 클래스
10장 문자열 클래스와 파일 클래스
 

More from Ji Hun Kim

Doing data science Chapter 9
Doing data science Chapter 9Doing data science Chapter 9
Doing data science Chapter 9Ji Hun Kim
 
Arduino 소개, RC카 만들기
Arduino 소개, RC카 만들기Arduino 소개, RC카 만들기
Arduino 소개, RC카 만들기Ji Hun Kim
 
High performance networking in chrome
High performance networking in chromeHigh performance networking in chrome
High performance networking in chromeJi Hun Kim
 
Api design for c++ 6장
Api design for c++ 6장Api design for c++ 6장
Api design for c++ 6장Ji Hun Kim
 
Windbg랑 친해지기
Windbg랑 친해지기Windbg랑 친해지기
Windbg랑 친해지기Ji Hun Kim
 
Python packaging
Python packagingPython packaging
Python packagingJi Hun Kim
 

More from Ji Hun Kim (10)

Doing data science Chapter 9
Doing data science Chapter 9Doing data science Chapter 9
Doing data science Chapter 9
 
Ninja
NinjaNinja
Ninja
 
Arduino 소개, RC카 만들기
Arduino 소개, RC카 만들기Arduino 소개, RC카 만들기
Arduino 소개, RC카 만들기
 
High performance networking in chrome
High performance networking in chromeHigh performance networking in chrome
High performance networking in chrome
 
Api design for c++ 6장
Api design for c++ 6장Api design for c++ 6장
Api design for c++ 6장
 
Windbg랑 친해지기
Windbg랑 친해지기Windbg랑 친해지기
Windbg랑 친해지기
 
Code 25장
Code 25장Code 25장
Code 25장
 
Code 17장
Code 17장Code 17장
Code 17장
 
Code 10장
Code 10장Code 10장
Code 10장
 
Python packaging
Python packagingPython packaging
Python packaging
 

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자 이하 중괄호는 중괄호를 필요로 하는 것과 같은 줄에서 시작