diff --git a/README.md b/README.md index 1d3b804..c392ae7 100644 --- a/README.md +++ b/README.md @@ -39,95 +39,204 @@ ## 모던 자바스크립트가 다루는 개념 -[Rest Parameters](#rest-parameters) +[Let Declaration](#let-declaration) + +[Const Declaration](#const-declaration) + +[Spread Syntax](#spread-syntax) [Destructuring Assignment](#destructuring-assignment) +[Rest Parameters](#rest-parameters) + +[Rest Elements](#rest-elements) + [Default Parameter](#default-parameter) [Named Parameter](#named-parameter) -[Truthy and Falsy](#truthy-and-falsy) +[Promise](#promise) + +[Async Function](#async-function) + +--- + +# Let Declaration + +### 정의 -[Array.prototype.map](#arrayprototypemap) +블록 레벨 유효 범위를 갖는 지역 변수를 선언합니다. -Array.prototype.reduce +### 특징 -Array.prototype.filter +`let` 으로 선언한 변수는 재선언할 수 없습니다. -Array.prototype.includes +`let` 으로 선언한 변수는 값을 재할당 할 수 있습니다. -Array.prototype.every +`let` 은 블록 레벨 유효 범위를 가집니다. 블록 레벨은 모든 코드 블록을 의미합니다. 예를 들어 `함수`, `if`, `switch`, `for`, `while`, `try-catch`, ... 내부에서 선언된 `let` 변수는 외부에서 접근할 수 없습니다. -Array.prototype.some +### 참고 -String.prototype.split +`let` 으로 선언된 변수들은 코드를 읽을 때 변함(`mutable`)을 기대하게 만듭니다. 이는 코드 리뷰어가 해당 변수가 언제 바뀌는지 계속해서 추적하게 만듭니다. 이는 굉장히 피곤한 일입니다. 따라서 변하지 않는 변수들은 **언제나** 상수(`const`)로 선언하세요. -String.prototype.join +### 1. 재선언 불가능 -Object.entries +👉시나리오: `let` 이 `var` 과 다르게 재선언 할 수 없다는 걸 증명하세요. + +```js +var a +var a // 재선언 통과 + +let b +let b // -> SyntaxError: Identifier 'b' has already been declared 👍 +``` -Object.values +### 2. 재할당 -Object.keys +👉시나리오: `let` 이 `const` 와 다르게 재할당 가능한 걸 증명하세요. + +```js +let a = 1 +a = 2 // 재할당 가능 👍 + +const b = 1 +b = 2 // -> TypeError: Assignment to constant variable. +``` + +### 3. 유효 범위 + +👉시나리오: `let` 이 `var` 과 다르게 블록 유효 범위를 가지는걸 증명하세요. + +```js +if (true) { + var a = 1 + let b = 1 +} + +console.log(a) // -> 1 +console.log(b) // -> ReferenceError: b is not defined 👍 +``` --- -# Rest Parameters +# Const Declaration ### 정의 -Rest Parameters 는 정해지지 않은 수 매개변수를 **실제 배열**로 나타낼 수 있게 합니다. +블록 레벨 유효 범위를 갖는 **상수**를 선언합니다. -## 1. 나머지 매개변수 예시 +### 특징 -👉 시나리오: 개수가 정해지지 않은 매개변수를 입력 받아 이의 총 합을 구하는 함수를 작성하세요. +`const` 는 선언과 동시에 할당해야 합니다. 즉 언제나 초깃값을 필요로 합니다. + +`const` 는 재할당 할 수 없습니다. + +`const` 는 `let` 과 동일하게 블록 레벨 유효 범위를 가집니다. + +### 1. 선언과 동시에 할당 + +👉시나리오: `const` 가 선언과 동시에 할당해야 함을 증명하세요. -### 불—편 - ```js -function sum (a, b, ... y, z) { - return a + b + ... + y + z -} // [a-z] 까지 입력받을 수 있습니다. 즉 매개변수의 개수가 정해져 있습니다. 👎 - -console.log(sum(1, 2, 3, 4, 5, 6, 7, 8)) // [i-z] 까지 undefined, 때문에 NaN 출력 👎 +const a = 1 +const b // -> SyntaxError: Missing initializer in const declaration ``` -### 편—안 ✅ +### 2. 재할당 불가능 + +👉시나리오: `const` 가 재할당 불가능함을 증명하세요. ```js -function sum (...params) { - return params.reduce((prev, curr) => prev + curr) -} // 매개변수가 몇 개든 합을 잘 구합니다. +const a = 1 +a = 2 // -> TypeError: Assignment to constant variable +``` -console.log(sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)) // -> 55 👍 +### 3. 유효 범위 + +👉시나리오: `const` 가 `let` 과 동일하게 블록 레벨 유효 범위를 가지는 것을 증명하세요. + +```js +if (true) { + var a = 1 + const b = 1 +} + +console.log(a) // -> 1 +console.log(b) // -> ReferenceError: b is not defined 👍 ``` -## 2. 또 다른 나머지 매개변수 예시 +--- -👉 시나리오: 첫번째 매개변수와 나머지 매개변수를 곱한 배열을 반환하는 함수를 작성하세요. +# Spread Syntax + +### 정의 + +Spread Syntax 는 특정 객체 혹은 배열의 나머지 요소들을 어떤 객체 혹은 배열 리터럴에 풀어 놓습니다. + +### 특징 + +Spread Syntax 로 새로운 변수가 선언되지 않습니다. + +## 1. 배열 전개구문 + +## 활용 1: 안전한 복사 + +👉 시나리오: `arr1` 과 똑같은 `arr2` 를 만드세요. + +👉 조건: `arr1` 의 변형이 `arr2` 에 영향을 미치지 않게 하세요. + +### 불—편 + +```js +const arr1 = [1, 2, 3] +const arr2 = arr1 // arr2 는 arr1 를 참조합니다. + +arr1.push(4) + +console.log(arr1) // -> [ 1, 2, 3, 4 ] +console.log(arr2) // -> [ 1, 2, 3, 4 ] arr2 까지 변형됐습니다. 👎 +``` ### 편—안 ✅ ```js -function multiply (multiplier, ...params) { - return params.map(param => multiplier * param) -} +const arr1 = [1, 2, 3] +const arr2 = [...arr1] // arr1 를 구조 분해시켜 '새로운' 배열을 만듭니다. 👍 -console.log(multiply(5, 1, 2, 3, 4)) // -> [ 5, 10, 15, 20 ] 👍 +arr1.push(4) + +console.log(arr1) // -> [ 1, 2, 3, 4 ] +console.log(arr2) // -> [ 1, 2, 3 ] 👍 ``` -## 3. arguments 와 다른점 +## 2. 객체 전개구문 -`arguments` 는 유사 배열입니다. 때문에 `map, reduce, forEach` 와 같은 배열 메소드를 호출 할 수 없습니다. +## 활용 1: 안전한 객체 얕은 병합 + +👉 시나리오: 주어진 `obj1` 에 `obj2` 를 병합하세요. + +👉 조건1: 중복 필드가 있다면 `obj2` 의 값으로 덮어씌우세요. + +👉 조건2: 주어진 객체를 변형하지 마세요. + +### 불—편 ```js -function sum (a, b, c) { - // -> TypeError: arguments.reduce is not a function - return arguments.reduce((prev, curr) => prev + curr) -} +const obj1 = { a: 1, b: 1 } +const obj2 = { b: 2, c: 2 } -sum(1, 2, 3) +// 나쁘지 않습니다만 obj1 이 수정됩니다. 👎 +const merged = Object.assign(obj1, obj2) +``` + +### 편—안 ✅ + +```js +const obj1 = { a: 1, b: 1 } +const obj2 = { b: 2, c: 2 } + +// 모든 조건을 만족하며 심플합니다! 👍 +const merged = { ...obj1, ...obj2 } ``` --- @@ -142,7 +251,7 @@ sum(1, 2, 3) 객체를 구조 분해해봅시다. -### 활용 1: 기본값 할당 +## 활용 1: 기본값 할당 👉 시나리오: `me` 객체를 출력하세요. @@ -197,66 +306,142 @@ console.log('자동차', car) 배열을 구조 분해해봅시다. -### 활용 1: 안전한 복사 +👉 시나리오: 배열 `arr` 의 첫 번째와 세 번째 원소를 각각 `first` 와 `third` 변수에 할당 및 선언하세요. -👉 시나리오: `arr1` 과 똑같은 `arr2` 를 만드세요. +### 불—편 -👉 조건: `arr1` 의 변형이 `arr2` 에 영향을 미치지 않게 하세요. +```js +const arr = [1, 2, 3, 4] -### 불—편 +const first = arr[0] // 좀 더 심플하게 안될까요? +const third = arr[2] // 인덱스로 접근하지 않으면서요 +``` + +### 편—안 ✅ ```js -const arr1 = [1, 2, 3] -const arr2 = arr1 // arr2 는 arr1 를 참조합니다. +const arr = [1, 2, 3, 4] -arr1.push(4) +const [first, , third] = arr // 좋습니다. 👍 +``` -console.log(arr1) // -> [ 1, 2, 3, 4 ] -console.log(arr2) // -> [ 1, 2, 3, 4 ] arr2 까지 변형됐습니다. 👎 +--- + +# Rest Parameters + +### 정의 + +Rest Parameters 는 정해지지 않은 수 매개변수를 **실제 배열**로 나타낼 수 있게 합니다. + +## 1. 나머지 매개변수 예시 + +👉 시나리오: 개수가 정해지지 않은 매개변수를 입력 받아 이의 총 합을 구하는 함수를 작성하세요. + +### 불—편 + +```js +function sum (a, b, ... y, z) { + return a + b + ... + y + z +} // [a-z] 까지 입력받을 수 있습니다. 즉 매개변수의 개수가 정해져 있습니다. 👎 + +console.log(sum(1, 2, 3, 4, 5, 6, 7, 8)) // [i-z] 까지 undefined, 때문에 NaN 출력 👎 ``` ### 편—안 ✅ ```js -const arr1 = [1, 2, 3] -const arr2 = [...arr1] // arr1 를 구조 분해시켜 '새로운' 배열을 만듭니다. 👍 - -arr1.push(4) +function sum (...params) { + return params.reduce((prev, curr) => prev + curr) +} // 매개변수가 몇 개든 합을 잘 구합니다. -console.log(arr1) // -> [ 1, 2, 3, 4 ] -console.log(arr2) // -> [ 1, 2, 3 ] 👍 +console.log(sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)) // -> 55 👍 ``` -### 활용 2: 또 다른 안전한 복사 +## 2. 또 다른 나머지 매개변수 예시 -👉 시나리오: 주어진 `fruits` 배열을 이용해 첫번째 과일과 나머지 과일을 출력하세요. +👉 시나리오: 첫번째 매개변수와 나머지 매개변수를 곱한 배열을 반환하는 함수를 작성하세요. -### 불—편 +### 편—안 ✅ ```js -const fruits = ['🍎', '🍌', '🥝'] +function multiply (multiplier, ...params) { + return params.map(param => multiplier * param) +} -// apple 과 rest 는 fruits 를 참조합니다. -const apple = fruits.shift() // fruits 의 첫번째 원소를 제거하고, apple 에 할당 -const rest = fruits +console.log(multiply(5, 1, 2, 3, 4)) // -> [ 5, 10, 15, 20 ] 👍 +``` -console.log('첫번째 과일', apple) // -> 🍎 -console.log('나머지 과일', ...rest) // -> 🍌 🥝 +## 3. arguments 와 다른점 + +`arguments` 는 유사 배열입니다. 때문에 `map, reduce, forEach` 와 같은 배열 메소드를 호출 할 수 없습니다. + +```js +function sum (a, b, c) { + // -> TypeError: arguments.reduce is not a function + return arguments.reduce((prev, curr) => prev + curr) +} -console.log(fruits) // -> [ '🍌', '🥝'] fruits 배열이 변형됨 👎 +sum(1, 2, 3) ``` +--- + + +# Rest Elements + +### 정의 + +Rest Elements 는 객체나 배열의 나머지 요소들을 선언과 동시에 할당합니다. + +### 특징 + +나머지 요소에서 명시한 변수명이 선언되는 효과를 가지며 구조 분해 할당과 함께 사용 시 맨 마지막에 한 번만 위치할 수 있습니다. + +## 활용 1: 배열 나머지 요소 + +👉 시나리오: `arr` 배열의 첫번째 요소를 `first` 에 할당하고 나머지 요소를 `rest` 에 풀어 넣으세요. + ### 편—안 ✅ ```js -const fruits = ['🍎', '🍌', '🥝'] +const arr = [1, 2, 3, 4, 5] +const [first, ...rest] = arr + +console.log(first) // -> 1 +console.log(rest) // -> [ 2, 3, 4, 5 ] 👍 +``` + +## 활용 2: 객체 나머지 요소 + +👉 시나리오: `me` 객체의 `name` 필드만 `name` 에 할당하고 나머지 요소를 `rest` 에 풀어 넣으세요. + +### 불—편 + +```js +const me = { + name: '손당근', + hobby: '산책', + location: 'earth' +} -const [apple, ...rest] = fruits // 배열을 구조 분해시켜 apple 과 rest 가 fruits 를 참조하지 않도록 해줍니다. +// 더 심플하게 안될까요? +const name = me.name +const rest = { + hobby: me.hobby, + location: me.location +} +``` -console.log('첫번째 과일', apple) // -> 🍎 -console.log('나머지 과일', ...rest) // -> 🍌 🥝 +### 편—안 ✅ -console.log(fruits) // -> [ '🍎', '🍌', '🥝' ] fruits 배열 변형 안됨 👍 +```js +const me = { + name: '손당근', + hobby: '산책', + location: 'earth' +} + +const { name, ...rest } = me // 👍 ``` --- @@ -267,7 +452,7 @@ console.log(fruits) // -> [ '🍎', '🍌', '🥝' ] fruits 배열 변형 안됨 Default Parameter 는 매개변수에 기본 값을 할당합니다. -## 1. 매개변수 기본 값 +## 활용1: 매개변수 기본 값 👉 시나리오: 이름 그리고 나이를 출력하는 함수 `aboutMe` 를 작성하세요. @@ -347,7 +532,7 @@ aboutMe({ name: '손당근', age: 20 }) // -> 손당근 20 aboutMe({ age: 20, name: '손당근' }) // -> 손당근 20 ... 심지어 매개변수 순서까지 바껴도 잘 출력합니다! aboutMe({ name: '손당근' }) // -> 손당근 비공개 ... 나이를 넘기지 않았으므로 '비공개' 를 출력합니다. -aboutMe({ age: 20 }) // -> 비공개 비공개 +aboutMe({ age: 20 }) // -> 비공개 20 aboutMe({}) // -> 비공개 비공개 ... 둘 다 '비공개' 로 출력 가능합니다! ``` @@ -360,7 +545,7 @@ aboutMe({}) // -> 비공개 비공개 ... 둘 다 '비공개' 로 출력 가능 Named Parameter 는 매개변수에 이름을 지정해줍니다. -### 활용1: 선택적 매개변수 +## 활용1: 선택적 매개변수 👉 시나리오: 나이와 직업을 매개변수로 받고 출력하는 함수 `aboutMe` 를 작성하세요. @@ -395,7 +580,7 @@ aboutMe({ age: 20 }) // -> 나이 20 aboutMe({ job: '개발자' }) // -> 직업 개발자 ``` -### 활용2: 순서 없는 매개변수 +## 활용2: 순서 없는 매개변수 매개변수가 3개 이상이면 순서를 잘못 입력할 가능성이 큽니다. @@ -437,179 +622,230 @@ render({ --- -# Truthy and Falsy +# Promise -참과 거짓은 Boolean 을 기대하는 문맥에서 `true` `false` 로 평가되는 값입니다. +### 정의 -## 1. 거짓 값 +Promise 는 **비동기 작업**의 **상태**를 보관하고 추적합니다. -자바스크립트에는 총 7 가지 거짓 값이 존재합니다. +### 특징 (중요 🐉) -`false` +Promise 는 다음 중 하나의 **상태**를 가집니다. -`0` +- 대기(*pending)*: 이행하거나 거부되지 않은 초기 상태. +- 이행(*fulfilled)*: 연산이 성공적으로 완료됨. +- 거부(*rejected)*: 연산이 실패함. -`0n` +[출처: [MDN - Promise](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise)] -`''` +Promise 는 주어진 콜백 함수를 **단 한 번** 실행하며 그 **결과**를 보관합니다. 이러한 특성 때문에 Promise 의 상태는 한 번 결정되면 수정되지 않습니다. -`null` +다시 말해 이미 소비(이행되거나 거부) 된 Promise 는 재사용 할 수 없습니다. -`undefined` +### 1. 성공 케이스 (fulfilled) -`NaN` +### 활용 1: 비동기 호출의 상태를 추적하기 -### 활용 1: 배열이 비어있나 확인하기 +👉시나리오: 3초 후 주문한 음식이 배달됩니다. 도착 시 이를 출력하세요. -배열은 `length` 프로퍼티를 가지고 있습니다. 이를 검사해 배열이 비어있는지 확인 가능합니다. +👉조건1: 배달이 도착하기 전에는 절대로 빨래를 시작하지 마세요. ### 불—편 ```js -const arr = [1, 2, 3] - -if (arr.length === 0) { // 좀 더 심플하게 안될까요? - console.log('배열이 비어있음!') +function delivery () { + setTimeout(() => { console.log('배달 도착') }, 3000) } + +// 배달을 요청합니다. (비동기 함수 호출) +// 그러나 배달의 현재 상태를 추적하지는 않습니다. +delivery() +console.log('빨래 시작') + +// 결과 👎 +// -> 빨래 시작 ... 배달이 도착하기도 전에 빨래를 시작했습니다. +// -> 배달 도착 ``` + ### 편—안 ✅ ```js -const arr = [1, 2, 3] - -if (!arr.length) { // 👍 좋습니다! 0 은 Falsy 기 때문에 배열이 비어있다면 조건을 만족합니다. - console.log('배열이 비어있음!') +function delivery () { + return new Promise((resolve) => { + setTimeout(() => { + console.log('배달 도착') + resolve() + }, 3000) + }) } -``` -### 활용 2: 안전히 메소드 호출하기 +delivery().then(() => { + console.log('빨래 시작') // 배달이 도착 한 후 빨래를 시작합니다. +}) -존재하지 않는 함수를 호출하면 `TypeError: ... is not a function` 를 `throw` 합니다. +// 결과 👍 +// -> 배달 도착 +// -> 빨래 시작 -이를 방지하고자 방어적인 코드를 작성해봅시다. +``` -### 불—편 +### 2. 실패 케이스 (rejected) -```js -const notArray = 5000 +👉시나리오: 3초 후 주문한 음식이 배달됩니다. 그러나 월요일은 휴무입니다. -notArray.forEach(it => console.log(it)) // -> TypeError: notArray.forEach is not a function -``` +👉조건1: 휴무일에는(배달 거부 시) 맥도날드에 방문하세요. ### 편—안 ✅ ```js -const iAmNotArray = 5000 - -if (iAmNotArray.forEach) { - iAmNotArray.forEach(it => console.log(it)) // 👍 +function delivery (day) { + return new Promise((resolve, reject) => { + if (day === '월요일') { + reject(new Error()) + } + + setTimeout(() => { + resolve() + }, 3000) + }) } -``` -## 2. 참 값 +delivery('월요일').then(() => { + console.log('음식 받기') +}).catch(() => { + console.log('맥도날드 방문하기') +}) -위에서 언급한 거짓 값을 제외하면 모두 참 값입니다. +// 결과 👍 +// -> 맥도날드 방문하기 +``` + -### 활용1: 객체 요소 검사 +### 3. 일회성 -`movie` 객체를 참조해 <아이언맨> 이 한글 자막을 지원하는지 확인해 봅시다. +Promise 는 비동기 함수 호출의 결과를 정확히 보관할 의무를 가집니다. 한 번 정해진 결과는 수정되지 않으며 이를 지키기 위해서 주어진 실행 함수(`executor`)를 단 한 번만 실행합니다. -### 편—안 ✅ +👉시나리오: Promise 가 일회성이라는 것을 증명하세요. ```js -const movie = { - ironman: { - ko: '아이언맨 4', - en: 'Iron Man 4' - } -} +// new Promise 를 한순간 이미 프로미스 소진 +const promise = new Promise((resolve) => { + console.log('안녕') + resolve() +}) -// 좋습니다. 👍 -if (movie.ironman.ko) { - console.log('한글 자막 개봉') -} +promise.then() +promise.then() +promise.then() + +// 결과 👍 +// -> 안녕 ... 단 한 번 출력됨 ``` --- -# Array.prototype.map +# Async Function ### 정의 -`map` 은 주어진 배열의 **모든 원소**에 규칙을 적용한 **새로운 배열**을 생성합니다. +Promise 객체를 반환하는 함수 -### 특징 (중요🐉) +### 특징 -`map` 은 주어진 배열을 변형하지 않습니다. +Async Function 은 `await` 키워드를 사용 가능케 해줍니다. `await` 키워드는 Async Function 에서만 유효합니다. -`map` 은 첫 `callback` 함수가 실행되기 직전에 주어진 배열의 복사본을 생성합니다. 때문에 `callback` 함수를 실행하는 동안에 주어진 배열이 변형되어도 결과에 영향을 미치지 않습니다. +`await` 키워드는 Async Function 이 끝나길(`return or throw`) 기다립니다. -`map` 은 주어진 배열의 모든 원소에 `callback` 함수를 수행하는 것이 목표입니다. 따라서 중간에 `break or continue` 호출은 불가합니다. +Async Function 는 `return` 혹은 `throw` 문으로 끝낼 수 있습니다. -다시 말해 `map` 은 반복문이 아닙니다. +Async/Await 을 사용하면 일련의 비동기 작업을 비교적 쉽게 동기 방식으로 호출 가능케 해줍니다. -`map` 을 탈출하는 방법은 에러를 `throw` 하는 겁니다. 하지만 이 방법을 되도록 사용하지 마세요. `for` 문을 고려하는 게 더 나을지도 모릅니다. +### 참고 -### 예제 1 +예시 코드들은 간결한 코드를 보여주기 위해 `top-level-await` 기능이 탑재된 환경에서 진행했습니다. `top-level-await` 은 ECMAScript proposal stage 3 상태며 자세한 내용은 아래 링크를 참고해 주세요. -👉 시나리오: 배열 `numbers` 의 모든 원소에 2 를 곱한 새로운 배열 `result` 를 만드세요. +[tc39/proposal-top-level-await - GitHub](https://github.com/tc39/proposal-top-level-await) -### 불—편 +### 1. 비동기 작업하기 -```js -const numbers = [1, 2, 3, 4, 5] -const result = [] +👉시나리오: 구글 검색 페이지를 크롤링 해오세요. 크롤링을 완료하는 것을 기다리지 말고 `이메일을 전송` 하세요. -// 장황합니다. 👎 -for (let i = 0; i < numbers.length; i++) { - result.push(numbers[i] * 2) -} - -console.log(result) // -> [ 2, 4, 6, 8, 10 ] -``` +👉조건: Async Function 을 활용하세요. ### 편—안 ✅ ```js -const numbers = [1, 2, 3, 4, 5] -const result = numbers.map(number => { return number * 2 }) +async function google () { + // ... + console.log('구글 크롤링 완료') +} -console.log(result) // -> [ 2, 4, 6, 8, 10 ] +google() // 비동기적으로 실행됩니다. +console.log('이메일 전송') + +// 결과 👍 +// -> 이메일 전송 +// -> 구글 크롤링 완료 ``` -### 예제 2 +### 2. 비동기 작업을 기다리기 -👉 시나리오: 배열 `cities` 의 모든 원소에 `광역시` 문자열을 뒤에 붙인 새로운 배열 `metropolitanCities` 을 만드세요. +👉시나리오: 구글 검색 페이지를 크롤링 해오세요. 크롤링을 완료한 뒤 `이메일을 전송` 하세요. -### 불—편 +👉조건: Async Function 을 활용하세요. +### 편—안 ✅ ```js -const cities = ['부산', '대구', '인천', '광주'] -const metropolitanCities = [] - -// 장황합니다. 👎 -for (let i = 0; i < cities.length; i++) { - metropolitanCities.push(cities[i] + '광역시') +async function google () { + // ... + console.log('구글 크롤링 완료') } -console.log(metropolitanCities) // -> [ '부산광역시', '대구광역시', '인천광역시', '광주광역시' ] +await google() // await 키워드가 동기적으로 실행하도록 만들어줍니다. 👍 +console.log('이메일 전송') + +// 결과 👍 +// -> 구글 크롤링 완료 +// -> 이메일 전송 ``` +### 3. 결과 다루기 + +### 활용 1: 성공 (return) + +👉시나리오: `getUser` 함수로 사용자 정보를 가져오세요. 결과를 받아 `name` 필드의 값을 출력하세요. + +👉조건: `await` 키워드로 `getUser` 함수가 반환하는 값을 받아오세요. ### 편—안 ✅ ```js -const cities = ['부산', '대구', '인천', '광주'] -const metropolitanCities = cities.map(city => { return `${city}광역시` }) // 👍 +async function getUser () { + const result = await dbQuery() + return result +} + +const user = await getUser() // await 키워드가 getUser 함수의 반환을 기다립니다. 👍 -console.log(metropolitanCities) // -> [ '부산광역시', '대구광역시', '인천광역시', '광주광역시' ] +console.log(user.name) ``` -### 좀 더 심플하게 ✅ +### 활용2: 실패 (throw) + +👉시나리오: 배달 음식을 주문하세요. 배달이 도착하면(`return`) 음식을 먹고, 만약 주문이 취소되면(`throw`) 방문 포장을 해오세요. + +### 편—안 ✅ ```js -const cities = ['부산', '대구', '인천', '광주'] -const metropolitanCities = cities.map(city => `${city}광역시`) // 👍 +async function delivery () { + // ... + throw new Error('주문 취소!') +} -console.log(metropolitanCities) // -> [ '부산광역시', '대구광역시', '인천광역시', '광주광역시' ] +try { + await delivery() // await 키워드가 덕분에 비동기 호출의 실패를 다룰수 있습니다. 👍 + // ... 배달 음식 먹기 +} catch (error) { + // ... 방문 포장 해오기 +} ```