안녕세계
[SK고용디딤돌] Node.js (5/10) - 6주차 본문
[SK고용디딤돌] Node.js (5/10) - 6주차
Junhong Kim 2016. 8. 10. 18:05- JS는 함수형 언어이므로 함수를 최대한 활용, 가독성을 늘려야 한다.
- 사용자 입력값에 대한 default 설정이 중요
< 파일 복사 프로그램 >
var async = require('async');
var fs = require('fs');
var path = require('path');
var srcPath = (process.argv[2] === undefined) ? path.join(__dirname, process.argv[2]) : __filename;
var destPath = process.argv[3] || (srcPath + '.copy');
// __dirname : 프로그램이 위치한 경로
function readFile(callback) {
var reader = fs.createReadStream(srcPath);
var data = '';
reader.on('data', function(chunk) {
data += chunk;
});
reader.on('end', function() {
console.log('reading completed!!');
callback(null, data);
});
reader.on('error', function() {
callback('reading error occurred!!')
});
}
function writeFile(data, callback) {
var writer = fs.createWriteStream(destPath);
writer.write(data);
callback(null);
}
async.waterfall([readFile, writeFile], function(err) {
if (err) {
console.log(err);
return;
}
console.log('copy completed!!!');
});
< async 연습(1) >
var async = require('async');
function first (callback) {
async.waterfall([
function(cb) {
cb(null, 3 * 6);
},
function(arg1, cb) {
cb(null, arg1 + 2);
},
], function(err, result) {
if (err) return callback('error');
else callback(null, result);
});
}
function second (callback) {
async.waterfall([
function(cb) {
cb(null, 8 * 2);
},
function(arg1, cb) {
cb(null, arg1 / 3);
},
], function(err, result) {
if (err) return callback('error');
else callback(null, result);
});
}
async.parallel([first, second], function(err, results){
if(err) {
console.log(err);
} else {
console.log(results[0] - results[1]);
}
});
var async = require('async');
// 3 * 6
function first(callback1) {
var result = 3 * 6;
callback1(null, result);
}
// 3 * 6 + 2
function second(data, callback2) {
var result = data + 2 ;
callback2(null, result);
}
// 8 * 2 / 3
function third(data, callback3) {
var result = 8 * 2 / 3;
callback3(null, data - result);
}
async.waterfall([first, second, third], function(err, results) {
if(err) {
console.log(err);
} else {
console.log(results);
}
});
- series 직렬 수행, 결과 값을 저장
- parallel 병행 수행
- waterfall 결과 값을 다음 task로 사용.
async waterfall 이나 series 같은 기능을 구현할 수 있다.
가독성이 좋아진다 는 장점
promise를 사용하기위해서는 ECMAScript6를 사용해야함
< promise (async waterfall 의 성능을 같음) vs async (asyncsms parallel 이라는 강력한 기능을 사용 가능 >
/**
* Created by Tacademy on 2016-08-10.
*/
// promise : 미래에 실행 될 코드를 등록하는 promise함수의 객체
// resolve : 약속이 해결되었을 때
// reject : 약속이 실패했을 때
var async = require('async');
var fs = require('fs');
var path = require('path');
var srcPath = (process.argv[2] !== undefined) ? path.join(__dirname, process.argv[2]) : __filename;
var destPath = process.argv[3] || (srcPath + '.copy');
function readFile() {
return new Promise(function(resolve, reject) {
var reader = fs.createReadStream(srcPath);
var data = '';
reader.on('data', function(chunk) {
data += chunk;
});
reader.on('end', function() {
resolve(data); // then의 1번째
});
reader.on('error', function() {
reject('readable stream error...'); // then의 2번째
});
});
}
// 미래 실행될 코드를 등록해논 것, 성공하면 resolve. 가져야할 value는 데이터이다.
function writeFile(value) {
return new Promise(function(resolve, reject) {
var writer = fs.createWriteStream(destPath);
writer.on('finish', function() {
resolve('copy completed!!!');
});
writer.on('error', function() {
reject('writer stream error...');
});
writer.write(value);
writer.end(); // flushing... all &
});
}
// promise객체는 내부적으로 실행을 하려면 then 이라는 함수를 호출하게끔 되어있다.
// then에는 함수의 매개변수로 두개의 함수를 받는다.
// resolve함수의 결과값은 첫번째 함수의 value값으로 넘어간다, 성공했을 때
// reject함수의 결과값은 두번째 함수의 reason값으로 넘거간다, 실패했을때
/*
promise.then(function(value) {
console.log(value.toString());
}, function(reason) {
console.log(reason);
});*/
/*
promise.then(function(value) {
console.log(value.toString());
}).then(null, function (reason) {
console.log(reason);
})*/
readFile().then(writeFile)
.then(function(value) {
console.log(value);
})
.catch(function(reason) { // error 오면 잡음
console.log(reason);
});
< contact.json - promise >
/**
* Created by Tacademy on 2016-08-10.
*/
var fs = require('fs');
var path = require('path');
function readFile() {
return new Promise(function(resolve, reject) {
var reader = fs.createReadStream(path.join(__dirname, '/contact.json'));
var data = '';
reader.on('data', function(chunk) {
data += chunk;
});
reader.on('end', function() {
resolve(data);
});
reader.on('error', function() {
reject('readable stream error...'); // then의 2번째
});
});
}
function parseToJSON(value) {
return new Promise(function(resolve) {
resolve(JSON.parse(value));
});
}
function printName(value) {
console.log('이름 :', value['name']);
return value;
}
function printAge(value) {
console.log('나이 :', value['age']);
return value;
}
function printGender(value) {
console.log('성별 :', value['gender']);
return value;
}
function printPhone(value) {
console.log('전화 :', value['phone']);
return value;
}
readFile().then(parseToJSON) // then에 들어온 인자가 함수면 return 값을 인자로 만듬, then에 들어가면 promise 객체가 됨
.then(printName)
.then(printAge)
.then(printGender)
.then(printPhone)
.catch(function(reason) { // error 오면 잡음
console.log(reason);
});
1) 제이슨 표기법, 표준
2) osi 7 layer 의 tcp/ip 4layer 관계
conten-type 내가 보내는것의 타입을 정의하는 것임 -> postㅇ
< REST서비스 >
- Code On Demand : 실행 가능한 코드 전송으로 기능 확장
- 정적리소스는 파일로 존재한다. (a.jpg, 1.html 등)
- 동적리소스는 요청에의해서 동적으로 생성되는 리소스
- 이것을 APP과 연결하는 것을 REST API라고하고 이를 각각 URI 또는 URL이라고 한다
''Method : Http Verb''
C : 리소스 생성하려면 POST
R : 리소스 읽으려면 GET
U : 리소스 변경하려면 PUT
D : 리소스 제거하려면 DELETE
GET http://www.example.com/articles?pageNo=1&count=10 기사목록
GET http://www.example.com/articles/1234 기사조회
ㄴ resource (복수형으로 표현, colletions라고도 함)
POST http://www.exampale.com/aricles 기사입력
PUT http://www.exampale.com/articles/1234 기사 변경
delet http://www.exampale.com/articles/1234 기사 삭제
http://host/collections/[{id}][?param=value]
1234 -> 리소스 ID(=컬렉션 ID)
*family photo 서비스
특정연도, 특정사용자가만든 포토를 서비스하려고한다. 여기에 적절한 url을
CRUD + L
* 특정 사용자 정보는 세션에 존재(URL에 표시X)
[GET] http:// ~ /familyphots 모든 사용자의 모든 family photo가 목록 조회
★(세션인증필요)[POST] http:// ~ /familyphotos '특정 사용자'의 '특정년도'의 '가족사진' 생성
[GET] http:// ~ /familyphotos?year=2015 특정사용자의 특정년도(2015년)의 가족사진 목록
[GET] http:// ~ /familyphotos/1111 특정사진(아이디) 조회
★(세션인증필요)[PUT] http:// ~ /familyphotos/1111 특정사진 변경
★(세션인증필요)[DELETE] http:// ~ /familyphotos/1111 특정사진 삭제
[GET] http:// ~ / familyphotos?userid=test@example.com 특정 사용자의 가족사진 목록 조회
★(세션인증필요)[GET] http:// ~ /profiles/me 특정 자신의 프로필 보기
get/collections -> 목록
[GET] http:// ~ /familyphotos/me 내 가족 사진
me와 같은 식별자를 동적 라우팅 파라미터라고한다.
세션 정보를 읽어서 그 아이디에 대한 db를 얻어서본다-> 동적 라우팅 파라미터
※ 필터를 제외한 URL이 공통된 부분을 하나로 합친다.
동적 라우팅 파라미터는 {}이렇게 표현한다.
node.js에서는 :param이라고한다 -> 이걸할 줄 알아야 프로토콜 정의서를 만들 수 있다.
포토 목록 [GET] http://www.example.com/familyphotos?yyyy=2105&user=chun&count=10&pageNo=1
포토 생성 [POST] http://www.example.com/familyphotos
포토 조회 [GET] http://www.example.com/familyphotos?yyyy=2015&user=chun
포토 변경 [PUT] http://www.example.com/familyphotos?yyyy=2015&user=chun
포토 삭제 [DELETE] http://www.example.com/familyphotos?yyyy=2015&user=chun
'My Trace > SK고용디딤돌2기' 카테고리의 다른 글
[SK고용디딤돌] Node.js (7/10) - 6주차 (0) | 2016.08.12 |
---|---|
[SK고용디딤돌] Node.js (6/10) - 6주차 (0) | 2016.08.11 |
[SK고용디딤돌] Node.js (4/10) - 6주차 (0) | 2016.08.09 |
[SK고용디딤돌] Node.js (3/10) - 6주차 (0) | 2016.08.08 |
[SK고용디딤돌] Node.js (2/10) - 5주차 (0) | 2016.08.05 |