일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 버킷생성
- Github
- 패키지설치에러
- gitlab
- Database
- 클라우드
- git
- aiapi
- 웹소켓연결
- javascript
- nodejs
- Express
- class
- 노드버전
- 웹소켓재시작
- 자바
- aws
- java
- nvmrc
- ChatGPT
- gpt3.5turbo
- iam사용자
- GPT3.5
- db
- gptapi
- 호스팅영역
- chatGPTAPI
- 웹소켓연결끊김
- 클래스
- openaiapi
- Today
- Total
IT's Jenna
Callback & Promise & async & await 본문
Javascript는 기본적으로 비동기 (Non-Blocking) 프로그래밍이다.
비동기 시스템이란, 동작이 스크립트가 작성된 순서대로 진행되는 것이 아니라 결과값이 먼저 나오는 순서대로 진행되는 것이다. 비동기 시스템은 주로 퍼포먼스가 극대화되어야 하는 웹/앱에서 많이 사용된다.
1. Non-Blocking
fs.readFile('./file.md', (err, data) => {
if (err) throw err;
console.log('non blocking data : ',data);
});
console.log('wow')
//result
//wow
//non blocking data : <Buffer 61 73 64 66 73 64 66>
스크립트가 작성된 절차대로 수행된다면 데이터가 먼저 출력되고 wow가 출력되겠지만, 비동기 방식은 그렇지 않다. console창에 wow를 출력하는 시간보다 데이터를 읽어오는 시간이 더 걸리기 때문에 위와 같은 결과가 나온다.
2. Callback
하지만, 스크립트를 작성하다보면 절차대로 진행되어야 하는 동작들이 생긴다. 이때 사용할 수 있는 방법 하나가 callback 함수이다. callback함수는 함수 안에서 실행되는 함수이다.
function sumFunction(num1, num2, callback){
let result = num1+num2
if('number' == typeof(result)){
let error
let message = result
callback(error, message)
} else {
let error = 'is Not Number : ', result
let message
callback(error, message)
}
}
sumFunction(1, "abcd",
function(error, message){ // callback 함수
console.log("error : ",error)
console.log("message : ",message)
}
)
//result
//error : is Not Number :
//message : undefined
위의 예제에서 sumFunction을 만들 때 callback함수가 실행될 부분에 'callback'을 넣어준다. 실제로 함수를 실행시킬 때 callback함수의 내용을 입력해주면 해당 callback 함수가 실행되어야 할 때에 동작한다.
3. Callback Hell
위와 같이 callback 함수를 사용해서 스크립트를 작성하다보면 callback 안에 callback을 넣고 또 그 안에 callback을 넣는 callback hell에 빠지게 된다.
setTimeout(() => {
console.log('sleep 2')
}, 3000);
setTimeout(() => {
console.log('wake up! 1')
}, 1000);
console.log('eat 0');
setTimeout(() => {
console.log('sleep')
setTimeout(() => {
console.log('wake up!')
setTimeout(() => {
console.log('eat');
}, 1000);
}, 1000);
}, 1000);
이때 Arrow function : () => 은 함수를 선언해주는 function()과 같다. 위와 같은 callback hell은 스크립트를 파악하기 쉽지 않다.
4. Promise 객체
Promise 객체를 활용해서 더욱 직관적으로 Non Blocking 코드를 제어할 수 있다. Promise가 비동기 코드를 제어할 수 있는 건 3가지 상태를 가지고 있기 때문이다. 3가지 상태는 다음과 같다.
- Pending(대기) : 이행되거나 거부되지 않은 초기 상태
- Fulfilled(이행) : 연산이 성공적으로 완료됨
- Rejected(실패) : 연산이 실패함
이제 위 3가지 상태를 어떻게 활용하는지 알아보자. 제목에서 말한 것처럼 Promise는 객체이기 때문에 사용할 때 new를 이용해서 인스턴스화 하면서 선언해준다. 여기서 Promise가 가지고 있는 2개의 콜백 함수 매개변수가 있다. 바로 resolve와 reject이다.
- Promise.resolve(value) : 이행된 promise값을 반환한다. (Fulfilled 상태)
- Promise.reject(reason) : 거부된 promise를 반환한다. 디버깅용으로 에러를 체크하기 위해 사용한다. (Rejected 상태)
5. async & await
동기화를 시켜주기 위해 Promise와 함께 사용하는 것이 async와 await이다. 말 그대로 (async) 비동기를 (await) 기다린다는 의미이다. 사용 방법은 다음과 같다.
- Promise의 결과값을 받아와서 사용해야 하는 함수 앞에 async를 입력한다.
- Promise에서 반환되는 값 앞에 await를 입력한다.
function promise(){
return new Promise((resolve, reject) => {
setTimeout(function(){
resolve("Success!");
}, 250);
});
}
async function promisetest(){
console.log('Test-Promise ' + await promise())
}
promisetest()
//result
//Test-Promise Success!
이때, 인스턴스화 한 Promise앞에 return을 붙여주는 이유는 promise()의 반환 값으로 resolve값을 내보내기 위해서다.
let myFirstPromise = new Promise((resolve, reject) => {
setTimeout(function(){
resolve("Success!"); // Yay! Everything went well!
}, 250);
});
console.log('myFirstPromise : ',myFirstPromise)
//result
//myFirstPromise : Promise { <pending> }
위와 같이 return값을 반환하지 않고 선언만 해준 Promise의 결과는 Promise 그 자체이다. 실제로 사용하고자 하는 promise의 resolve 또는 reject값을 얻기 위해서는 return을 사용하여 값을 반환해주는 것이 편리하다.
<참고>
developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve
'Backend > Backend 기본' 카테고리의 다른 글
모듈화 (0) | 2021.01.27 |
---|---|
Database 상태변화 (0) | 2021.01.27 |
Injection attak (0) | 2021.01.23 |
Express 환경 사용하기 3 - 라우팅 (0) | 2021.01.20 |
Express 환경 사용하기 2 - 미들웨어 (0) | 2021.01.19 |