저번에 정리해 놓았던 동기, 비동기 덕분에 이번에 공부한 Promise, async, await를 이해하는데에 큰 도움이 되었다. 여윽시 블로그는 나만의 성지.....나만의....나만....😭
오늘 dfs도 구현을 해봤는데, 생각보다 쉽게 구현했다!
드디어 재귀를 깨우친 것인가....라는 착각을 하면서 오늘 공부한 비동기에 대해서 정리해보자.
귀릿🔥
call back, promise, async/await가 왜 나온거여?
위에 3가지가 왜 필요한지,,,왜 나온건지,,, 생각해보자!
동기는 한가지 요청을 받으면, 그 일을 처리해주기 전까지 다른일은 STOP!
이렇게 표현해도 맞을지 모르겠지만, 비동기는 한번에 여러개의 요청을 받아서, 한번에 처리!
그런데....자바스크립트는 기본적으로 싱글스레드!
한꺼번에 요청을 받아도 한 가지 일씩 순서대로 처리해주어야한다!
결론적으로 순.서.대.로. 일을 처리해주기 위해서 위와 같은 3가지 skill이 나온 것이다.
캬캬캬캬캬컄 난천재야 캬캬캬ㅑ컄
callback으로 비동기 처리
1) 동기function foo1() { console.log('A'); console.log('B'); console.log('C'); } foo1(); /* OUTPUT : A B C */
- 이것은 동기!!
- A라는 주문을 받고 처리해줘야, B라는 주문을 받을 수 있고
- B라는 주문을 받고 처리해줘야, C를 받아 처리할 수 있는거지!
2) 비동기
function foo2() { setTimeout(function(){ console.log('A'); setTimeout(function(){ console.log('B'); setTimeout(function(){ console.log('C'); },500) },1000) },2000) } foo2(); /* OUTPUT : (2초뒤에) A B C */
- 위에 코드가 뙇 비동기 처리방식이지 않궷뉘?!
- setTimeout때문에 헷갈릴 수 있지만, 그건 신경쓰지말고 내가 설명하는 것에 집중해보자!
- 위에 setTimeout의 인자인 콜백함수안에 setTimeout이 또 있는것이 보일꺼여?
- 첫번째 셋타임아웃의 밀리세컨드가 2000이니깐, 2초뒤에 함수가 실행되고 두번째, 세번째 셋타임 아웃의 함수들은 각각 1초 0.5초뒤에 실행되겠지?
- 그러면 세번째 셋타임아웃은 0.5초뒤에 함수를 실행시키니까 C가 제일 먼저 출력이 될 것 같잖아???
- 하지만 아니라는거지....콜백함수로 내가 A,B,C 차례로 순서를 정의해줬기 때문에 백날 밀리세컨드 바꿔도 A,B,C가 나온다 이거야~
- A,B,C에 대한 요청을 한번에 받고 마지막 요청인 C가 제일 일찍 끝났어도, 내가 A,B,C로 순서를 정의해줬으니까 A,B,C 순서로 출력이 되는거지! 후후..
Promise의 생성과 3가지 상태
- 프로미스를 사용할 때 알아야 하는 가장 기본적인 개념이 바로 프로미스의 상태(states)이다. 여기서 말하는 상태란 프로미스의 처리 과정을 의미한다. new Promise()로 프로미스를 생성하고 종료될 때까지 3가지 상태를 갖는다.
1. Pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태
🎈 먼저 아래와 같이 new Promise() 메서드를 호출하면 대기(Pending) 상태가 된다.🎈 new Promise() 메서드를 호출할 때 콜백 함수를 선언할 수 있고, 콜백 함수의 인자는 resolve, reject이다.new Promise();
2. Fulfilled(이행) : 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태new Promise(function(resolve, reject) { // ... });
🎈 여기서 콜백 함수의 인자 resolve를 아래와 같이 실행하면 이행(Fulfilled) 상태가 된다.3. Rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태new Promise(function(resolve, reject) { resolve(); });
🎈 new Promise()로 프로미스 객체를 생성하면 콜백 함수 인자로 resolve와 reject를 사용할 수 있다고 했다. 여기서 reject를 아래와 같이 호출하면 실패(Rejected) 상태가 된다.new Promise(function(resolve, reject) { reject(); });
then과 catch의 특징
🎈 기본적으로 then과 catch의 리턴 값은 Promise 객체이다.
🎈 첫 번째 특징으로 then과 catch는 resolve, reject의 처리 결과 값을 받을 수 있다.
🎈 정리하면, then은 Promise 객체를 반환하고, 그 Promise 객체의 resolve가 리턴해주는 값을 다음 then의 인자로 받을 수 있는 특성은 chain을 가능하게 만든다.
🎈 두 번째 특징으로 then과 catch의 인자는 콜백함수이기 때문에, 콜백함수안에 함수를 실행해줌으로써 비동기에서 중요한 순서의 정의를 내려줄 수 있다.var newsURL = 'http://localhost:5000/data/latestNews'; var weatherURL = 'http://localhost:5000/data/weather'; function getNewsAndWeather() { let obj = {}; return fetch(newsURL) .then(res => res.json()) .then(json => { obj['news'] = json.data; return fetch(weatherURL) }) .then(res => res.json()) .then(json => { obj['weather'] = json; return obj; }) }
🎈 콜백함수안에서 자체적으로 return문을 사용할 수 있는데, 이럴 때는 Promise 객체를 리턴시키는 가정하에 실행한다고 추측해본다.
resolve와 then, reject와 catch의 관계
🎈 resolve & then : 이행 상태가 되면 아래와 같이 then()을 이용하여 처리 결과 값을 받을 수 있다.function getData() { return new Promise(function(resolve, reject) { var data = 100; resolve(data); }); } // resolve()의 결과 값 data를 resolvedData로 받음 getData().then(function(resolvedData) { console.log(resolvedData); // 100 });
🎈 rejecte & catch : 실패 상태가 되면 실패한 이유(실패 처리의 결과 값)를 catch()로 받을 수 있다.
function getData() { return new Promise(function(resolve, reject) { reject(new Error("Request is failed")); }); } // reject()의 결과 값 Error를 err에 받음 getData().then().catch(function(err) { console.log(err); // Error: Request is failed });
await를 쓰는 함수는 함수명 앞에 async를 명시한다.
🎈 await를 할당 받는 변수는 Promise객체의 resolve 혹은 reject의 결과 값을 받게 된다.
🎈 await 뒤에는 Promise를 반환하는 함수가 와야 한다. (그게 아니면 의미가 없어버려!!!!!!)async function getNewsAndWeatherAsync() { let 변수1 = await Promise 반환 함수 let 변수2 = await Promise 반환 함수 . . . }
🎈 async & await 간단한 예제
function fetchItems() { return new Promise(function(resolve, reject) { var items = [1,2,3]; resolve(items) }); } async function logItems() { var resultItems = await fetchItems(); console.log(resultItems); // [1,2,3] }
🎈 async & await 간단한 예제
async function logTodoTitle() { try { var user = await fetchUser(); if (user.id === 1) { var todo = await fetchTodo(); console.log(todo.title); // delectus aut autem } } catch (error) { console.log(error); } }
fs.readFile(filePath, 'utf8', function (err, data) {
if(err){
callback(err, null);
}
else{
callback(err, data)
}
});
fetch(URL)
.then(response => response.json())
.then(json => console.log(json))
.catch(error => console.log(error));
오늘은 여기까지!
file system에 관한 함수와 fetch는 간단한 사용법만 알아보았는데, 더 사용해보고 블로깅 할 예정이다.
MDN을 보니까 fetch는 두번째 인자로 post, get 등 서버의 요청하는 방식을 설정할 수 있는 것 같다. 얼른 실습하러 다시 가보자!!!
우하하하하하!!!!!!! 나는 포기하지 않아 이자식들아!!!!!!!!
드루와!!!!!
👻👻👻