일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 게시판
- 출처 : https://webdir.tistory.com/506
- 출처 : https://joshua1988.github.io/web-development/javascript/promise-for-beginners/
- https://velog.io/@velopert/create-typescript-react-component
- object
- http://jeonghwan-kim.github.io/dev/2019/06/25/react-ts.html
- toString
- Today
- Total
Back Ground
NodeJS - ES2015+ 본문
객체 리터럴
객체 리터럴에는 편리한 기능들이 추가되었다.
- ES5
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | var sayNode = function(){ console.log('Node'); } var es = 'ES'; var oldObject = { sayJS : function(){ console.log('JS'); }, sayNode : sayNode, }; oldObject[es + 6] = 'Fantastic'; oldObject.sayNode(); // Node oldObject.sayJS(); //JS console.log(oldObject.ES6); //Fantastic | cs |
oldObject 객체에 동적으로 속성을 추가하고 있다.
앞의 코드를 다음과 같이 다시 쓸 수 있다.
- ES6
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | var sayNode = function(){ console.log('Node'); } var es = 'ES'; const newObject = { sayJS(){ console.log('JS'); }, sayNode, [es + 6] : 'Fantastic', }; newObject.sayNode(); // Node newObject.sayJS(); //JS console.log(newObject.ES6); //Fantastic | cs |
oldObject와 newObject 를 비교해서 보면 된다.
sayJS 같은 객체의 메서드에 함수를 연결할 때 더는 : 과 function을 붙이지 않아도 된다.
sayNode: sayNode처럼 속성명과 변수명이 겹치는 경우에는 한 번만 쓸 수 있게 되었다.
스크립트에서 다음과 같은 경우가 많이 나오는데, 이때 코드의 중복을 피할 수 있어 편리하다.
1 2 | { name : name, age : age } //ES5 { name, age } //ES2015 | cs |
객체의 속성명을 동적으로 생성할 수 있다.
예전 문법에서는 ES6라는 속성명을 만들려면 객체 리터럴(oldObject) 바깥에서 [ es + 6 ]를 해야 했다.
객체 리터럴에 추가된 문법은 코딩 시 편의를 위해 만들어진 것이라는 느낌이 강하다.
익숙해지면 코드의 양을 많이 줄일 수 있다.
비구조화 할당
이름은 어색하지만 매우 유용한 기능이다.
객체와 배열로 부터 속성이나 요소를 쉽게 꺼낼 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 | var candyMachine = { statue: { name : 'node', count : 5, } }, getCandy: function(){ this.status.count--; return this.status.count; } }; var getCandy = candyMachine.getCandy; var count = candyMachine.status.count; | cs |
객체의 속성을 같은 이름의 변수에 대입하는 코드이다.
이를 다음과 같이 바꿀 수 있다.
1 2 3 4 5 6 7 8 9 10 11 | const candyMachine = { statue: { name : 'node', count : 5, }, getCandy(){ this.status.count--; return this.status.count; } }; const { getCandy, status : {count} } = candyMachine; | cs |
당황스럽겠지만, 위 문법은 유효한 문법이다.
candyMachine 객체 안의 속성을 찾아서 변수와 매칭해준다.
const처럼 여러 단계 안의 속성도 찾을 수 있다.
getCandy와 count 변수가 초기화 된 것
배열도 비구조화이다.
1 2 3 4 | var array = ['nodejs' , {}, 10, true]; var node = array[0]; var obj = array[1]; var bool = array[array.length -1]; | cs |
array란 배열의 첫 번째, 두번째 요소와 마지막 요소를 변수에 대입하는 코드이다.
다음과 같이 바꿀 수 있다.
1 2 | const array = ['nodejs',{}, 10, true]; const [node, obj, bool] = array; | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | const condition = true; // true면 resolve, false면 reject const promise = new Promise( (resolve, reject) => { if(condition){ resolve('성공'); }else{ reject('실패'); } }); promise .then( (message) => { console.log(message); // 성공(resolve)한 경우 실행 }) .catch( (error) => { console.error(error); // 실패(reject)한 경우 실행 }); | cs |
resolve와 reject에 넣어준 인자는 각각 then과 catch의 매개변수에서 받을 수 있다.
즉, resolve('성공')가 호출되면 then의 message가 '성공'이 된다.
만약 reject('실패')가 호출되면 catch의 error가 '실패'가 되는 것이다.
condition 변수를 false로 바꿔보면 catch에서 에러가 로깅된다.
then이나 catch에서 다시 다른 then이나 catch를 붙일 수 있다.
이전 then의 return값을 다음 then의 매개변수로 넘긴다.
프로미스를 return한 경우 프로미스가 수행된 후 다음 then이나 catch가 호출된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | promise .then( (message) => { return new Promise( (resolve, reject) => { resolve(message2); }); }) .then( (message2) => { console.log(message2); return new Promise( (resolve, reject) => { resolve(message2); }); }) .then( (message3) ) =>{ console.log(message3); }) .catch( (error) => { console.error(error); }) }); | cs |
처음 then에서 message를 resolve하면 다음 then에서 받을 수 있다.
여기서 다시 message2를 resolve했으므로 다음 then에서 message3를 받는다.
이것을 활용해서 콜백을 프로미스로 바꿀 수 있다. 다음은 콜백을 쓰는 콜백을 쓰는 패턴 중 하나이다.
이를 프로미스로 바꿔보겠다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | function findAndSaveUser(Users){ Users.findOne( {}, ( err, user ) => { //첫 번째 콜백 if(err){ return console.error(err); } user.name = 'zero'; user.save( (err) => { // 두 번째 콜백 if(err){ return console.error(err); } } Users.findOne( {gender : 'm'}, (err, user) => { // 세 번째 콜백 //생략 }); }); }); } | cs |
콜백 함수가 세 번 중첩되어 있다.
콜백 함수가 나올 때마다 코드의 깊이가 깊어진다.
각 콜백 함수마다 에러도 따로 처리해줘야 한다.
이 코드를 다음과 같이 바꿀 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | function findAndSaveUser(Users){ Users.findOne( {} ) .then( (user) => { user.name = 'zero'; return user.save(); }) .then( (user) => { return Users.findOne( {gender : 'm' }); }) .then( (user) => { // 생략 }) .catch( err => { console.error(err); }); } | cs |
코드의 깊이가 더 이상 깊어지지 않다.
then메소드들은 순차적으로 실행 된다.
콜백에서 매번 따로 처리해야 했던 에러도 마지막 catch에서 한번에 처리할 수 있다.
하지만 모든 콜백함수를 위와 같이 바꿀 수 있는 것은 아닙니다.
메서드가 프로미스 방식을 지원해야 한다.
예제의 코드는 findOne과 save메서드가 내부적으로 프로미스 객체를 가지고 있어서 가능한 것이다.
1 2 3 4 5 6 7 8 9 | const promise1 = Promise.resolve('성공1'); const promise2 = Promise.resolve('성공2'); Promise.all([promise1, promise2]) .then( ( result) => { console.log(result); // ['성공1', '성공2'] }) .catch( (error) => { console.error(error); }); | cs |
Promise.resolve는 즉시 resolve하는 프로미스를 만드는 방법이다.
비슷한 것으로 즉시 reject하는 Promise.reject도 있다.
프로미스가 여러 개 있을 때 Promise.all에 넣으면 모두 resolve될 때까지 기다렸다가 then으로 넘어간다.
result 매개변수에 각각의 프로미스 결괏값이 배열로 들어 있다.
Promise 중 하나라도 reject가 되면 catch로 넘어간다.
async/await
노드 7.6 버전부터 지원되는 기능있다.
자바스크립트 스펙은 ES2017이다. 최신 기능이면서 정말 혁신적인 기능이다.
특히 노드처럼 비동기 프로그래밍을 해야 할 때 도움이 많이 된다.
프로미스가 콜백 지옥을 해결했다지만, 여전히 코드가 장황한다.
async/await 문법은 프로미스를 사용한 코드를 한 번 더 깔끔하게 줄여준다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | function findAndSaveUser(Users){ Users.findOne({}) .then( (user) => { user.name = 'zero'; return user.save(); }) .then( (user) => { return Users.findOne( {gender: 'm'}); }) .then( (user) => { // 생략 }) .catch( err => { console.error(err); }); } | cs |
콜백과 다르게 코드의 깊이가 깊진 않지만,
코드 길이는 여전히 깁니다. async/await 문법을 사용하면 다음과 같이 바꿀 수 있다.
async function이라는 것이 추가 되었다.
1 2 3 4 5 6 7 | async function findAndSaveUser(Users){ let user = await Users.findOne( {} ); user.name = 'zero'; user = await user.save(); user = await Users.findOne( {gender: 'm'} ); // } | cs |
놀라운 정도로 코드가 짧아졌다.
함수 선언부를 일반 함수 대신 async function으로 교체한 후,
프로미스 앞에 awit을 붙여주었다.
이제 함수는 해당 프로미스가 resolve될 때까지 기다린 뒤 다음 로직으로 넘어간다.
예를 들면 awit User.findOne({})이 resolve될 때 까지 기다린 뒤, user 변수를 초기화 하는 것이다.
'Javascript > Node.js' 카테고리의 다른 글
Node - Node 기능 (0) | 2019.02.15 |
---|---|
Callback Hell 이란 [ 해결방법 ] (2) | 2019.01.23 |
NodeJS - RestFul [ES5] (0) | 2018.11.11 |
NodeJS - Router 사용해 요청 라우팅하기 [ES5] (0) | 2018.10.07 |
NodeJS - Static [ES5] (0) | 2018.10.07 |