SlideShare a Scribd company logo
2017. 4. 15
한장현
, 잘 쓰고 계시죠?
• 전 삼성SDS 선임
• TV플랫폼 JavaScript 어플리케이션 구현
• 리테일 솔루션 서버 & 프론트엔드 구현
• 퇴사 1년째 자유의 몸
• JavaScript Full-stack Engineer
• 블로그 : han41858.tistory.com
• GitHub : github.com/han41858
• Angular 번역서 집필중
• GDG Korea Web Tech 운영진
한장현 (Janghyun Han)
2
History
’97. 6
ES1
’98. 6
ES2
’99. 12
ES3
’07. 10
ES4
’09. 12
ES5
’11. 6
ES5.1
’16. 6
ES7
’15. 6
ES6
’17. 4
Transpiler
ES6 ⇒ ES5
Variables & Constants
var
let
const
값이 바뀌면
값이 바뀌지 않으면
* 호이스팅 주의
console.log(x);
var x = 'hello';
> undefined > Uncaught ReferenceError: x is not defined
console.log(x);
const x = 'hello';
console.log(x);
let x = 'hello';
Enhanced Object Literals
var firstName = 'Janghyun';
var lastName = 'Han';
console.log({
firstName : firstName,
lastName : lastName
});
const firstName = 'Janghyun';
const lastName = 'Han';
console.log({
firstName,
lastName
});
=
Arrow Function Expression
const sum = (num1, num2) => {
return num1 + num2;
}
const sum = (num1, num2) => num1 + num2;
function sum (num1, num2) {
return num1 + num2;
}
const sum = function (num1, num2) {
return num1 + num2;
}
or
* 호이스팅 됨
* function을 완전히 대체하지는 않음. new 불가
함수의 몸체가 한 줄이면 중괄호 & return 생략
Arrow Function Expression
인자가 1개면 괄호 생략 가능 인자가 없으면 괄호 생략 불가
const log = text => {
console.log(text);
}
log('hello');
const log = () => {
console.log('hello');
}
log();
Arrow Function Expression
lexical this
> name is :
function runner (name) {
this.name = name;
setTimeout(function () {
console.log('name is : ', this.name);
}, 1000);
}
const newRunner = new runner('hello');
function runner (name) {
this.name = name;
setTimeout(() => {
console.log('name is : ' + this.name);
}, 1000);
}
const newRunner = new runner('hello');
> name is : hello
Template Literals
const name = 'Janghyun';
console.log('my name is ' + name);
console.log(`my name is ${name}`);
> my name is Janghyun
const address = 'korean'
+ 'seoul';
console.log(address);
const address = `korea
seoul`;
console.log(address);
> korea
seoul
=
Template Literals
> Janghyun Han
Tagged Template Literals
function fullName (string, firstName, lastName) {
console.log(string); // ['', 'is ', '']
return firstName + ' ' + lastName;
}
const firstName = 'Janghyun';
const lastName = 'Han'
console.log(fullName`${firstName} is ${lastName}`);
forEach(), for-in, for-of
var arr = ['a', 'b', 'c'];
for (var i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
arr.forEach(one => {
console.log(one);
});
for(let i in arr){
console.log(arr[i]);
}
for(let i of arr){
console.log(i);
}
> a
b
c
← break 불가
Parameter Default Value
function log (str) {
str = str || '(empty)';
console.log(str);
}
log();
function log (str = '(empty)') {
console.log(str);
}
log();
=
Rest Operator, Spread Operator
나머지 연산자
function log (){
var people = [].slice.call(arguments);
people.forEach(person => {
console.log(person);
});
}
log('Han', 'Kim', 'Lee'); // 개수 가변
function log (...people) {
people.forEach(person => {
console.log(person);
});
}
log('Han', 'Kim', 'Lee'); // 개수 가변
=
> Han
Kim
Lee
function log (one, two, ...rest) {
console.log(one);
console.log(two);
console.log(rest);
}
log(1, 2, 3, 4, 5);
> 1
2
[3, 4, 5]
Rest Operator, Spread Operator
전개 연산자
const arr = [1, 2, 3];
console.log(arr); // [1, 2, 3]
console.log(...arr); // 1 2 3
console.log(1, 2, 3); // 1 2 3
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const arr3 = arr1.concat(arr2);
const arr4 = [...arr1, ...arr2];
console.log(arr3); // [1, 2, 3, 4, 5, 6]
console.log(arr4); // [1, 2, 3, 4, 5, 6]
Destructuring
객체 비구조화
function getStock(){
return {
symbol: "IBM",
price: 100.00
};
}
const { symbol, price } = getStock();
console.log(`${symbol} is $${price}`);
> IBM is $100
function getStock () {
return {
symbol : "IBM",
price : 100.00
};
}
const result = getStock();
const symbol = result.symbol;
const price = result.price;
console.log(`${symbol} is $${price}`);
=
Destructuring
배열 비구조화
> Kim
Han
> Kim
Han
["Lee", "Park"]
let [name1, name2] = ['Kim', 'Han'];
console.log(name1);
console.log(name2);
let [name1, name2, ...rest] = ['Kim', 'Han', 'Lee', 'Park'];
console.log(name1);
console.log(name2);
console.log(rest);
Class & Inheritance
> Child {familyName: "Han", firstName: "Janghyun"}
true
true
class Parent {
constructor (familyName) {
this.familyName = 'Han';
}
}
class Child extends Parent {
constructor (firstName, familyName) {
super(familyName);
this.firstName = firstName;
}
}
const me = new Child('Janghyun', 'Han');
console.log(me);
console.log(me instanceof Child);
console.log(me instanceof Parent);
사실은 prototype
Class getter & setter
> Person {}
> Person {_name: "Janghyun"}
class Person {
get name (){
return this._name;
}
set name (name){
this._name = name;
}
}
const person = new Person();
console.log(person);
person.name = 'Janghyun';
console.log(person);
무한루프 조심
Class getter & setter
함수 선언
const person = new Person();
person.walk();
person.sleep();
function Person () {
return {
walk : function () {
console.log('walking...');
},
sleep : function () {
console.log('sleeping...');
}
}
}
class Person {
walk () {
console.log('walking...');
}
sleep () {
console.log('sleeping...');
}
}
=
객체 리터럴에도 해당
Class Static Function
class Dog {
static bite () {
console.log('BITE!!');
}
}
Dog.bite();
> BITE!!
Module – import & export
export & import { }
export default & import
export const number = 100;
import { number } from './test'
console.log(number);
export default const number = 100;
import number from './test'
console.log(number);
import { number as num } from './test'
console.log(num);
or
or
import num from './test'
console.log(num);
권장
Promise
static delete (param) {
const self = this;
return util.objValidate(param, {
userID : Constants.TYPE.EMAIL
}, Constants.ERROR.USER_CTRL.NO_PARAMETER, log, 'delete()')
.then(param => self.isExists(param))
.then(param => {
// delete records
return recordCtrl.deleteAll({
userID : param.userID
})
.then(() => {
log('remove records ok');
// param 자체를 다시 돌려주기 위해 Promise 필요
return Promise.resolve(param);
});
})
.then(param => {
// delete cards
return cardCtrl.deleteAll({
userID : param.userID
})
.then(() => {
log('remove cards ok');
return Promise.resolve(param);
});
})
.then(param => {
// delete assets
return assetCtrl.deleteAll({
userID : param.userID
})
.then(() => {
log('remove assets ok');
return Promise.resolve(param);
});
})
.then(param => {
// delete user
return User.remove({
userID : param.userID
})
.then(() => {
return Promise.resolve(param);
}, error => {
log(error);
return Promise.reject(new ERROR(Constants.ERROR.MONGOOSE.REMOVE_FAILED, log, 'delete()'));
});
})
.then(param => {
log(`delete ok : ${param.userID}`);
return Promise.resolve(true);
});
}
비동기 작업을 동기처럼 실행
쓰는 목적은 가독성 향상
콜백지옥 해결 X
Promise
thenable
pending
fulfilled : Promise.resolve() – then()
rejected : Promise.reject() – catch()
Promise
Promise.resolve()
.then(() => {
console.log('then 1');
})
.then(() => {
console.log('then 2');
});
기본 형태
Promise.resolve('a')
.then(param => {
console.log('then 1', param);
return Promise.resolve('b');
})
.then(param => {
console.log('then 2', param);
});
인자 전달
> then 1, a
then 2, b
> then 1
then 2
Promise
에러 처리
Promise.resolve()
.then(() => {
console.log('then 1');
return Promise.reject();
})
.then(() => {
console.log('then 2');
})
.catch(() => {
console.log('catch');
});
> then 1
catch
Promise.resolve()
.then(() => {
console.log('then 1');
return Promise.reject();
})
.then(() => {
console.log('then 2');
}, () => {
console.log('catch');
});
=
Promise
new Promise()
Promise.resolve(), Promise.reject()와 다름
함수 실행 스택을 새로 시작
Promise를 지원하지 않는 비동기 함수 처리
Promise.resolve()
.then(() => {
setTimeout(() => {
console.log('in setTimeout()');
}, 1000);
})
.then(() => {
console.log('final then');
});
> final then
in setTimeout()
잘못된 방법
Promise.resolve().then(() => {
return new Promise(resolve => {
setTimeout(() => {
console.log('in setTimeout()');
resolve();
}, 1000);
})
}).then(() => {
console.log('final then');
});
> in setTimeout()
final then
Promise
병렬 처리
Promise.all([
Promise.resolve(1),
Promise.resolve(2),
Promise.resolve(3)
])
.then(result => {
console.log(result);
});
> [1, 2, 3]
Promise.all([
Promise.resolve(1),
Promise.resolve(2),
Promise.reject(3)
])
.then(result => {
console.log(result);
})
.catch(error => {
console.log(error);
});
병렬 오류 처리
> 3
Promise const promise1 = new Promise(resolve => {
const delay = 100;
setTimeout(() => {
console.log('delay', delay);
resolve(delay);
}, delay);
});
const promise2 = new Promise(resolve => {
const delay = 200;
setTimeout(() => {
console.log('delay', delay);
resolve(delay);
}, delay);
});
const promise3 = new Promise(resolve => {
const delay = 300;
setTimeout(() => {
console.log('delay', delay);
resolve(delay);
}, delay);
});
Promise.all([
promise1,
promise2,
promise3
])
.then(result => {
console.log('then', result);
});
Promise
빠른것 하나만 처리
DB 인스턴스가 여러 개일 때
백엔드가 여러 지역에 있을 때
const promise1 = new Promise(resolve => {
const delay = 100;
setTimeout(() => {
console.log('delay', delay);
resolve(delay);
}, delay);
});
const promise2 = new Promise(resolve => {
const delay = 200;
setTimeout(() => {
console.log('delay', delay);
resolve(delay);
}, delay);
});
const promise3 = new Promise(resolve => {
const delay = 300;
setTimeout(() => {
console.log('delay', delay);
resolve(delay);
}, delay);
});
Promise.race([
promise1,
promise2,
promise3
])
.then(result => {
console.log('then', result);
});
Generator
비동기 처리
yield는 return과 비슷, yield 뒤 구문은 실행되고 반환
function* generatorFnc () {
yield 1;
}
var iterator = generatorFnc();
console.log(iterator); // Generator {}
console.log(iterator.next()); // { value : 1, done : false }
console.log(iterator.next()); // { value : undefined, done : true }
function* generatorFnc () {
yield 1;
yield 2;
yield 3;
}
var iterator = generatorFnc();
console.log(iterator); // Generator {}
console.log(iterator.next()); // { value : 1, done : false }
console.log(iterator.next()); // { value : 2, done : false }
console.log(iterator.next()); // { value : 3, done : false }
console.log(iterator.next()); // { value : undefined, done : true }
Generator
그만 알아보자
next() 표준 아님
send() 표준 아님
close() 표준 아님
throw() 표준 아님
function* fibonacci() {
var a = yield 1;
yield a * 2;
}
var it = fibonacci();
console.log(it); // "Generator { }"
console.log(it.next()); // 1
console.log(it.send(10)); // 20
console.log(it.close()); // undefined
console.log(it.next()); // throws StopIteration (as the generator is now closed)
표준인 것
generator*
yield
yield*
Async & Await – ES7 Draft
async : AsyncFunction 객체, 반환하는 것은 Promise, 결국 Promise wrapper
> some logic
then() : hello
> some logic
then() : hello
=
async function asyncFnc (msg) {
console.log('some logic');
return msg;
}
asyncFnc('hello')
.then(msg => {
console.log('then() :', msg);
});
const asyncFnc = function (msg) {
return Promise.resolve()
.then(() => {
console.log('some logic');
return Promise.resolve(msg);
});
}
asyncFnc('hello')
.then(msg => {
console.log('then() :', msg);
});
const asyncFnc = async msg => {
console.log('some logic');
return msg;
}
화살표 함수 표현식도 가능!!
Async & Await – ES7 Draft
async 에러 처리
async function asyncFnc (msg) {
console.log('some logic');
throw msg;
}
asyncFnc('hello')
.then(msg => {
console.log('then() :', msg);
})
.catch(error => {
console.error('catch() :', error);
});
const asyncFnc = function (msg) {
return Promise.resolve()
.then(() => {
console.log('some logic');
return Promise.reject(msg);
});
}
asyncFnc('hello')
.then(msg => {
console.log('then() :', msg);
})
.catch(error => {
console.error('catch() :', error);
});
=
> some logic
catch() : hello
> some logic
catch() : hello
Async & Await – ES7 Draft
await : 현재 구문을 멈추고 다른 Promise를 실행, 그 Promise 완료되면 다시 진행
function delayFnc (delay, number) {
console.log('delayFnc()', delay, number);
return new Promise(resolve => {
setTimeout(() => {
resolve(number);
}, delay);
});
}
async function add1 () {
var a = delayFnc(500, 10);
var b = delayFnc(1000, 5);
return await a + await b;
}
add1().then(sum => {
console.log(sum);
});
async function add2 () {
var a = await delayFnc(500, 10);
var b = await delayFnc(1000, 5);
return a + b;
}
add2().then(sum => {
console.log(sum);
});
병렬 처리 === Promise.all()
확인용 딜레이 함수
순차 처리
Async & Await – ES7 Draft
Async 는 Promise Wrapper!! 기존 Promise 로직도 호환
비동기 함수 랩핑에는 new Promise() 필요
.resolve()
.reject()
.then()
.catch()
.all()
async & return
async & throw
async & .then()
async & .catch()
async & await
=
Async & Await – ES7 Draft
Promise Async
const delayFnc = (delay, result) => {
return new Promise(resolve => {
setTimeout(() => {
resolve(result);
}, delay);
});
}
const request1 = async () => {
console.log('request1() start');
return delayFnc(1000, {
msg : 'Hello'
});
}
const request2 = async () => {
console.log('request2() start');
return delayFnc(1000, {
msg : 'Async'
});
}
const parse = async (dataArr) => {
return dataArr
.map(data => data.msg)
.join(' ');
}
(async () => {
const dataArr = [await request1(), await request2()];
const result = await parse(dataArr);
console.log(result);
})();
function delayFnc (delay, result) {
return new Promise(resolve => {
setTimeout(() => {
resolve(result);
}, delay);
});
}
function request1 () {
console.log('request1() start');
return delayFnc(1000, {
msg : 'Hello'
});
}
function request2 () {
console.log('request2() start');
return delayFnc(2000, {
msg : 'Async'
});
}
function parse (dataArr) {
return Promise.resolve(
dataArr
.map(data => data.msg)
.join(' ')
);
}
Promise.all([request1(), request2()])
.then(dataArr => parse(dataArr))
.then(result => {
console.log(result);
});
Async & Await – ES7 Draft
에러 처리 (from MDN)
Promise Async
function getProcessedData (url) {
return downloadData(url)
.catch(e => {
return downloadFallbackData(url)
})
.then(v => {
return processDataInWorker(v);
});
}
async function getProcessedData (url) {
let v;
try {
v = await downloadData(url);
} catch (e) {
v = await downloadFallbackData(url);
}
return processDataInWorker(v);
}
More things…
Array
from()
of()
fill()
find()
findIndex()
entries()
keys()
values()
copyWithin()
Map, Set
forEach()
entries()
keys()
values()
WeakMap, WeakSet
clear()
Math
imul()
clz32()
fround()
log10()
log2()
log1p()
expm1()
cosh()
sinh()
tanh()
acosh()
asinh()
atanh()
hypot()
trunc()
sign()
cbrt()
Number
isNan()
isFinite()
isInteger()
parseInt()
parseFloat()
EPSILON
MAX_SAFE_INTEGER
MIN_SAFE_INTEGER
isSafeInteger()
Object
is()
setPrototypeOf()
assign()
getOwnPropertySymbols()
String
fromCodePoint()
codePointAt()
startsWith()
endsWith()
includes()
repeat()
normalize()
raw()
Symbol
iterator
for()
match
Coverage
ES5
ES6
TypeScript
Q & A
감사합니다.

More Related Content

ES6, 잘 쓰고 계시죠?

  • 1. 2017. 4. 15 한장현 , 잘 쓰고 계시죠?
  • 2. • 전 삼성SDS 선임 • TV플랫폼 JavaScript 어플리케이션 구현 • 리테일 솔루션 서버 & 프론트엔드 구현 • 퇴사 1년째 자유의 몸 • JavaScript Full-stack Engineer • 블로그 : han41858.tistory.com • GitHub : github.com/han41858 • Angular 번역서 집필중 • GDG Korea Web Tech 운영진 한장현 (Janghyun Han) 2
  • 3. History ’97. 6 ES1 ’98. 6 ES2 ’99. 12 ES3 ’07. 10 ES4 ’09. 12 ES5 ’11. 6 ES5.1 ’16. 6 ES7 ’15. 6 ES6 ’17. 4
  • 5. Variables & Constants var let const 값이 바뀌면 값이 바뀌지 않으면 * 호이스팅 주의 console.log(x); var x = 'hello'; > undefined > Uncaught ReferenceError: x is not defined console.log(x); const x = 'hello'; console.log(x); let x = 'hello';
  • 6. Enhanced Object Literals var firstName = 'Janghyun'; var lastName = 'Han'; console.log({ firstName : firstName, lastName : lastName }); const firstName = 'Janghyun'; const lastName = 'Han'; console.log({ firstName, lastName }); =
  • 7. Arrow Function Expression const sum = (num1, num2) => { return num1 + num2; } const sum = (num1, num2) => num1 + num2; function sum (num1, num2) { return num1 + num2; } const sum = function (num1, num2) { return num1 + num2; } or * 호이스팅 됨 * function을 완전히 대체하지는 않음. new 불가 함수의 몸체가 한 줄이면 중괄호 & return 생략
  • 8. Arrow Function Expression 인자가 1개면 괄호 생략 가능 인자가 없으면 괄호 생략 불가 const log = text => { console.log(text); } log('hello'); const log = () => { console.log('hello'); } log();
  • 9. Arrow Function Expression lexical this > name is : function runner (name) { this.name = name; setTimeout(function () { console.log('name is : ', this.name); }, 1000); } const newRunner = new runner('hello'); function runner (name) { this.name = name; setTimeout(() => { console.log('name is : ' + this.name); }, 1000); } const newRunner = new runner('hello'); > name is : hello
  • 10. Template Literals const name = 'Janghyun'; console.log('my name is ' + name); console.log(`my name is ${name}`); > my name is Janghyun const address = 'korean' + 'seoul'; console.log(address); const address = `korea seoul`; console.log(address); > korea seoul =
  • 11. Template Literals > Janghyun Han Tagged Template Literals function fullName (string, firstName, lastName) { console.log(string); // ['', 'is ', ''] return firstName + ' ' + lastName; } const firstName = 'Janghyun'; const lastName = 'Han' console.log(fullName`${firstName} is ${lastName}`);
  • 12. forEach(), for-in, for-of var arr = ['a', 'b', 'c']; for (var i = 0; i < arr.length; i++) { console.log(arr[i]); } arr.forEach(one => { console.log(one); }); for(let i in arr){ console.log(arr[i]); } for(let i of arr){ console.log(i); } > a b c ← break 불가
  • 13. Parameter Default Value function log (str) { str = str || '(empty)'; console.log(str); } log(); function log (str = '(empty)') { console.log(str); } log(); =
  • 14. Rest Operator, Spread Operator 나머지 연산자 function log (){ var people = [].slice.call(arguments); people.forEach(person => { console.log(person); }); } log('Han', 'Kim', 'Lee'); // 개수 가변 function log (...people) { people.forEach(person => { console.log(person); }); } log('Han', 'Kim', 'Lee'); // 개수 가변 = > Han Kim Lee function log (one, two, ...rest) { console.log(one); console.log(two); console.log(rest); } log(1, 2, 3, 4, 5); > 1 2 [3, 4, 5]
  • 15. Rest Operator, Spread Operator 전개 연산자 const arr = [1, 2, 3]; console.log(arr); // [1, 2, 3] console.log(...arr); // 1 2 3 console.log(1, 2, 3); // 1 2 3 const arr1 = [1, 2, 3]; const arr2 = [4, 5, 6]; const arr3 = arr1.concat(arr2); const arr4 = [...arr1, ...arr2]; console.log(arr3); // [1, 2, 3, 4, 5, 6] console.log(arr4); // [1, 2, 3, 4, 5, 6]
  • 16. Destructuring 객체 비구조화 function getStock(){ return { symbol: "IBM", price: 100.00 }; } const { symbol, price } = getStock(); console.log(`${symbol} is $${price}`); > IBM is $100 function getStock () { return { symbol : "IBM", price : 100.00 }; } const result = getStock(); const symbol = result.symbol; const price = result.price; console.log(`${symbol} is $${price}`); =
  • 17. Destructuring 배열 비구조화 > Kim Han > Kim Han ["Lee", "Park"] let [name1, name2] = ['Kim', 'Han']; console.log(name1); console.log(name2); let [name1, name2, ...rest] = ['Kim', 'Han', 'Lee', 'Park']; console.log(name1); console.log(name2); console.log(rest);
  • 18. Class & Inheritance > Child {familyName: "Han", firstName: "Janghyun"} true true class Parent { constructor (familyName) { this.familyName = 'Han'; } } class Child extends Parent { constructor (firstName, familyName) { super(familyName); this.firstName = firstName; } } const me = new Child('Janghyun', 'Han'); console.log(me); console.log(me instanceof Child); console.log(me instanceof Parent); 사실은 prototype
  • 19. Class getter & setter > Person {} > Person {_name: "Janghyun"} class Person { get name (){ return this._name; } set name (name){ this._name = name; } } const person = new Person(); console.log(person); person.name = 'Janghyun'; console.log(person); 무한루프 조심
  • 20. Class getter & setter 함수 선언 const person = new Person(); person.walk(); person.sleep(); function Person () { return { walk : function () { console.log('walking...'); }, sleep : function () { console.log('sleeping...'); } } } class Person { walk () { console.log('walking...'); } sleep () { console.log('sleeping...'); } } = 객체 리터럴에도 해당
  • 21. Class Static Function class Dog { static bite () { console.log('BITE!!'); } } Dog.bite(); > BITE!!
  • 22. Module – import & export export & import { } export default & import export const number = 100; import { number } from './test' console.log(number); export default const number = 100; import number from './test' console.log(number); import { number as num } from './test' console.log(num); or or import num from './test' console.log(num); 권장
  • 23. Promise static delete (param) { const self = this; return util.objValidate(param, { userID : Constants.TYPE.EMAIL }, Constants.ERROR.USER_CTRL.NO_PARAMETER, log, 'delete()') .then(param => self.isExists(param)) .then(param => { // delete records return recordCtrl.deleteAll({ userID : param.userID }) .then(() => { log('remove records ok'); // param 자체를 다시 돌려주기 위해 Promise 필요 return Promise.resolve(param); }); }) .then(param => { // delete cards return cardCtrl.deleteAll({ userID : param.userID }) .then(() => { log('remove cards ok'); return Promise.resolve(param); }); }) .then(param => { // delete assets return assetCtrl.deleteAll({ userID : param.userID }) .then(() => { log('remove assets ok'); return Promise.resolve(param); }); }) .then(param => { // delete user return User.remove({ userID : param.userID }) .then(() => { return Promise.resolve(param); }, error => { log(error); return Promise.reject(new ERROR(Constants.ERROR.MONGOOSE.REMOVE_FAILED, log, 'delete()')); }); }) .then(param => { log(`delete ok : ${param.userID}`); return Promise.resolve(true); }); } 비동기 작업을 동기처럼 실행 쓰는 목적은 가독성 향상 콜백지옥 해결 X
  • 24. Promise thenable pending fulfilled : Promise.resolve() – then() rejected : Promise.reject() – catch()
  • 25. Promise Promise.resolve() .then(() => { console.log('then 1'); }) .then(() => { console.log('then 2'); }); 기본 형태 Promise.resolve('a') .then(param => { console.log('then 1', param); return Promise.resolve('b'); }) .then(param => { console.log('then 2', param); }); 인자 전달 > then 1, a then 2, b > then 1 then 2
  • 26. Promise 에러 처리 Promise.resolve() .then(() => { console.log('then 1'); return Promise.reject(); }) .then(() => { console.log('then 2'); }) .catch(() => { console.log('catch'); }); > then 1 catch Promise.resolve() .then(() => { console.log('then 1'); return Promise.reject(); }) .then(() => { console.log('then 2'); }, () => { console.log('catch'); }); =
  • 27. Promise new Promise() Promise.resolve(), Promise.reject()와 다름 함수 실행 스택을 새로 시작 Promise를 지원하지 않는 비동기 함수 처리 Promise.resolve() .then(() => { setTimeout(() => { console.log('in setTimeout()'); }, 1000); }) .then(() => { console.log('final then'); }); > final then in setTimeout() 잘못된 방법 Promise.resolve().then(() => { return new Promise(resolve => { setTimeout(() => { console.log('in setTimeout()'); resolve(); }, 1000); }) }).then(() => { console.log('final then'); }); > in setTimeout() final then
  • 28. Promise 병렬 처리 Promise.all([ Promise.resolve(1), Promise.resolve(2), Promise.resolve(3) ]) .then(result => { console.log(result); }); > [1, 2, 3] Promise.all([ Promise.resolve(1), Promise.resolve(2), Promise.reject(3) ]) .then(result => { console.log(result); }) .catch(error => { console.log(error); }); 병렬 오류 처리 > 3
  • 29. Promise const promise1 = new Promise(resolve => { const delay = 100; setTimeout(() => { console.log('delay', delay); resolve(delay); }, delay); }); const promise2 = new Promise(resolve => { const delay = 200; setTimeout(() => { console.log('delay', delay); resolve(delay); }, delay); }); const promise3 = new Promise(resolve => { const delay = 300; setTimeout(() => { console.log('delay', delay); resolve(delay); }, delay); }); Promise.all([ promise1, promise2, promise3 ]) .then(result => { console.log('then', result); });
  • 30. Promise 빠른것 하나만 처리 DB 인스턴스가 여러 개일 때 백엔드가 여러 지역에 있을 때 const promise1 = new Promise(resolve => { const delay = 100; setTimeout(() => { console.log('delay', delay); resolve(delay); }, delay); }); const promise2 = new Promise(resolve => { const delay = 200; setTimeout(() => { console.log('delay', delay); resolve(delay); }, delay); }); const promise3 = new Promise(resolve => { const delay = 300; setTimeout(() => { console.log('delay', delay); resolve(delay); }, delay); }); Promise.race([ promise1, promise2, promise3 ]) .then(result => { console.log('then', result); });
  • 31. Generator 비동기 처리 yield는 return과 비슷, yield 뒤 구문은 실행되고 반환 function* generatorFnc () { yield 1; } var iterator = generatorFnc(); console.log(iterator); // Generator {} console.log(iterator.next()); // { value : 1, done : false } console.log(iterator.next()); // { value : undefined, done : true } function* generatorFnc () { yield 1; yield 2; yield 3; } var iterator = generatorFnc(); console.log(iterator); // Generator {} console.log(iterator.next()); // { value : 1, done : false } console.log(iterator.next()); // { value : 2, done : false } console.log(iterator.next()); // { value : 3, done : false } console.log(iterator.next()); // { value : undefined, done : true }
  • 32. Generator 그만 알아보자 next() 표준 아님 send() 표준 아님 close() 표준 아님 throw() 표준 아님 function* fibonacci() { var a = yield 1; yield a * 2; } var it = fibonacci(); console.log(it); // "Generator { }" console.log(it.next()); // 1 console.log(it.send(10)); // 20 console.log(it.close()); // undefined console.log(it.next()); // throws StopIteration (as the generator is now closed) 표준인 것 generator* yield yield*
  • 33. Async & Await – ES7 Draft async : AsyncFunction 객체, 반환하는 것은 Promise, 결국 Promise wrapper > some logic then() : hello > some logic then() : hello = async function asyncFnc (msg) { console.log('some logic'); return msg; } asyncFnc('hello') .then(msg => { console.log('then() :', msg); }); const asyncFnc = function (msg) { return Promise.resolve() .then(() => { console.log('some logic'); return Promise.resolve(msg); }); } asyncFnc('hello') .then(msg => { console.log('then() :', msg); }); const asyncFnc = async msg => { console.log('some logic'); return msg; } 화살표 함수 표현식도 가능!!
  • 34. Async & Await – ES7 Draft async 에러 처리 async function asyncFnc (msg) { console.log('some logic'); throw msg; } asyncFnc('hello') .then(msg => { console.log('then() :', msg); }) .catch(error => { console.error('catch() :', error); }); const asyncFnc = function (msg) { return Promise.resolve() .then(() => { console.log('some logic'); return Promise.reject(msg); }); } asyncFnc('hello') .then(msg => { console.log('then() :', msg); }) .catch(error => { console.error('catch() :', error); }); = > some logic catch() : hello > some logic catch() : hello
  • 35. Async & Await – ES7 Draft await : 현재 구문을 멈추고 다른 Promise를 실행, 그 Promise 완료되면 다시 진행 function delayFnc (delay, number) { console.log('delayFnc()', delay, number); return new Promise(resolve => { setTimeout(() => { resolve(number); }, delay); }); } async function add1 () { var a = delayFnc(500, 10); var b = delayFnc(1000, 5); return await a + await b; } add1().then(sum => { console.log(sum); }); async function add2 () { var a = await delayFnc(500, 10); var b = await delayFnc(1000, 5); return a + b; } add2().then(sum => { console.log(sum); }); 병렬 처리 === Promise.all() 확인용 딜레이 함수 순차 처리
  • 36. Async & Await – ES7 Draft Async 는 Promise Wrapper!! 기존 Promise 로직도 호환 비동기 함수 랩핑에는 new Promise() 필요 .resolve() .reject() .then() .catch() .all() async & return async & throw async & .then() async & .catch() async & await =
  • 37. Async & Await – ES7 Draft Promise Async const delayFnc = (delay, result) => { return new Promise(resolve => { setTimeout(() => { resolve(result); }, delay); }); } const request1 = async () => { console.log('request1() start'); return delayFnc(1000, { msg : 'Hello' }); } const request2 = async () => { console.log('request2() start'); return delayFnc(1000, { msg : 'Async' }); } const parse = async (dataArr) => { return dataArr .map(data => data.msg) .join(' '); } (async () => { const dataArr = [await request1(), await request2()]; const result = await parse(dataArr); console.log(result); })(); function delayFnc (delay, result) { return new Promise(resolve => { setTimeout(() => { resolve(result); }, delay); }); } function request1 () { console.log('request1() start'); return delayFnc(1000, { msg : 'Hello' }); } function request2 () { console.log('request2() start'); return delayFnc(2000, { msg : 'Async' }); } function parse (dataArr) { return Promise.resolve( dataArr .map(data => data.msg) .join(' ') ); } Promise.all([request1(), request2()]) .then(dataArr => parse(dataArr)) .then(result => { console.log(result); });
  • 38. Async & Await – ES7 Draft 에러 처리 (from MDN) Promise Async function getProcessedData (url) { return downloadData(url) .catch(e => { return downloadFallbackData(url) }) .then(v => { return processDataInWorker(v); }); } async function getProcessedData (url) { let v; try { v = await downloadData(url); } catch (e) { v = await downloadFallbackData(url); } return processDataInWorker(v); }
  • 39. More things… Array from() of() fill() find() findIndex() entries() keys() values() copyWithin() Map, Set forEach() entries() keys() values() WeakMap, WeakSet clear() Math imul() clz32() fround() log10() log2() log1p() expm1() cosh() sinh() tanh() acosh() asinh() atanh() hypot() trunc() sign() cbrt() Number isNan() isFinite() isInteger() parseInt() parseFloat() EPSILON MAX_SAFE_INTEGER MIN_SAFE_INTEGER isSafeInteger() Object is() setPrototypeOf() assign() getOwnPropertySymbols() String fromCodePoint() codePointAt() startsWith() endsWith() includes() repeat() normalize() raw() Symbol iterator for() match
  • 41. Q & A

Editor's Notes

  1. https://ko.wikipedia.org/wiki/ECMA%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8 1997. 6 : ECMAScript 1 1998. 6 : ECMAScript 2 1999. 12 : ECMAScript 3 2007. 10 : ECMAScript 4 – 언어에 얽힌 정치적 견해 차이로 폐기 2009. 12 : ECMAScript 5 2011. 6 : ECMAScript 5.1 2015. 6 : ECMAScript 6 2016. 6 : ECMAScript 7 2017. 12? : ECMAScript 8
  2. https://developer.mozilla.org/ko/docs/Web/JavaScript/New_in_JavaScript/ECMAScript_6_support_in_Mozilla WeakMap, WeakSet은 key가 Object