250x250
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 스코프
- node
- 프로미스
- async/await
- nodeJS
- typescript
- 트랜잭션
- rebase
- pm2
- javascript
- manytomanyfield
- westagram
- Jest
- CORS
- 노드
- on_delete
- TypeError: this.boardRepository.createBoard is not a function
- OSI7계층
- crud2
- 호이스팅
- bcrypt
- JWT
- 실행 컨텍스트
- status code
- Django
- docker
- 자바스크립트
- django westagram
- wecode
- 장고초기세팅
Archives
- Today
- Total
될때까지
((비동기 처리방식)) 콜백, Promise, Async/await과 비동기 본문
728x90
🎯 동기와 비동기
동기(Synchronous)
- 현재 실행중인 코드가 끝나야 다음 코드를 실행한다.
- 현재 실행중인 작업이 끝날 때 까지 모두 동작 그만!! 다음 task는 대기한다.
- 장점 : 동기 처리는 코드를 순서대로 실행하기 때문에 실행 순서가 보장된다.
- 단점 : 현재 실행중인 task가 끝날 때 까지 다음 task는 실행을 못하며, task가 blocking되는 문제가 생긴다.
비동기(Asynchronous)
- 현재 실행중인 코드가 끝나지 않아도 다음 코드를 실행한다.
- 비동기 task는 실행하도록 브라우저에게 맡기고 다음 task로 넘어간다.
- 장점 : 블로킹이 발생하지 않기 때문에 여러개의 일을 처리할 수 있다.
- 단점 : 코드들의 실행 순서가 보장되지 않는다.
- 자바스크립트 엔진은 한번에 하나의 task만 실행할 수 있는 싱글 스레드 기반 언어다.
시간이 많이 걸리는 task의 경우 블로킹이 발생하고 다음 task는 해당 작업이 끝날때 까지 기다려야하므로 효율성이 떨어진다.
* 아래 코드의 실행결과를 예측해보자
setTimeout(function() {
console.log('1');
}, 0);
console.log('2');
for (let i = 0; i < 3; ++i) {
loop();
}
setTimeout(function() {
console.log('3');
}, 0);
console.log('4');
function loop() {
console.log('5');
}
--------> setTimeout은 비동기 처리함수이기 때문에 백그라운드로 작업을 넘기고 다음 코드가 실행된다.
2 -> 5, 5, 5(반복문 돌면서 loop() 실행) -> 4 -> 1, 4(백그라운드에 넘겼던 setTimeout의 실행 결과 출력)
🎯 콜백함수
- 자바스크립트에서는 함수도 객체(object)다.
- 함수는 다른 함수의 매개변수로 쓰일수도 있고, 어떤 함수의 실행 결과로 반환될 수도 있다. 이를 고차함수라고 한다.
- 함수의 매개변수가 함수일 때, 매개변수로 받은 함수를 콜백함수(함수 안에서 실행되는 또 다른 함수라고 생각하자)라고 한다.
- 콜백함수를 사용하면 비동기 처리 방식의 문제점(실행 순서 제어 불가)을 해결할 수 있다.
- 주의사항 : 콜백함수는 동기처리, 비동기 처리에 모두 쓰인다.
- 단점 : 비동기 함수가 처리 결과를 가지고 또 비동기 함수를 호출하면 콜백지옥을 일으킨다.
이로 인해 코드의 가독성이 떨어지고 에러 처리가 어렵다는 단점이 있다.(try catch로 에러 캐치 불가능)
🎯 Promise
- ES6에 도입된 비동기 동작을 처리하기 위한 클래스다.
- 프로미스 클래스를 인스턴스화 해서 프로미스 객체를 만들고 반환된 프로미스로 원하는 비동기 동작을 처리한다.
- resolve는 성공했을 때 실행할 함수이고 reject는 실패했을 때 실행할 함수다.
- 참고로 resolve와 reject는 미리 정의하지 않아도 자바스크립트 엔진에서 미리 정의해놓기 때문에 정의하지 않아도 호출에 문제가 없다.
- resolve와 reject는 여러번 호출해도 첫번째로 호출된 코드만 실행하고 종료된다. 같이 쓰인 경우, 먼저 쓰인 것만 호출되고 종료된다.
// 프로미스 구현하기
let promise = new Promise( function (resolve, reject) {
// 비동기 로직 작성
...생략...
resolve(); // 에러 발생 안함
reject();
})
resolve
- 성공적으로 실행을 마치면 resolve를 호출하고, resolve로 넘긴 콜백함수의 매개변수를 아래 .then에서 받을 수 있다.
let promise = new Promise(function (resolve, reject) {
setTimeout(function() {
resolve('promise success');
}, 2000);
});
promise.then(function (msg) {
console.log(msg); // 2초 뒤에 promise success 출력
})
reject
let promise = new Promise(function (resolve, reject) {
setTimeout(function(){
// 실패했다고 가정
reject('promise fail!');
}, 2000);
});
promise.then(function(){
console.log('resolve');
}).catch(function(err){
console.log('reject', err); // reject promise fail! 출력
});
Promise의 상태
- 프로미스 객체는 '상태'를 가지고 있다.
- pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태
- fulfilled(이행) : 비동기 처리가 완료되어 프로미스가 결과값을 반환한 상태
- rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태
let promise = new Promise(function(resolve, reject) {
setTimeout(function() {
console.log('before', promise) // before Promise { <pending> }
reject(1);
console.log('after', promise); // after Promise { <rejected> 1 }
}, 1000);
});
promise.then(function(msg) {
console.log('resolve', msg);
}, function (msg) {
console.log('reject', msg); // reject 1 출력
});
에러처리
- catch를 사용하여 처리하는 게 가독성이 좋다.
let promise = new Promise(function(resolve, reject) {
setTimeout(function() {
reject('에러처리!');
}, 2000);
});
promise
.then(function() {
})
.catch(function(err) {
console.log(err);
});
function job() {
return new Promise(function(resolve, reject) {
reject();
});
}
job()
.then(function() {
console.log(1);
})
.then(function() {
console.log(2);
})
.then(function() {
console.log(3);
})
.catch(function() {
console.log(4);
})
.then(function() {
console.log(5);
});
// 콘솔에 4만 찍힐 것 같았는데 4,5가 찍혔다.
// catch에서 잡고 나서 then은 실행이 되나보다..!
// 맨 아래 then을 => catch로 바꾸면 4만 찍혔다.
Promise.finally()
- then()과 catch()다음에 적어주는 메소드로, 성공하든 실패하든 항상 실행되는 코드다.
Promise.all()
- 여러 비동기 함수의 실행이 모두 끝났을 때 받아서 처리하고 싶은 경우에 사용한다.
- 응답값은 배열로 한꺼번에 반환된다.
🎯 Async & await
- ES8에 도입되었고 async function은 promise를 반환한다.
- await을 쓰려면 반드시 async로 함수를 선언해야한다.
- 예외 처리는 try, catch를 사용하여 핸들링할 수 있다.
728x90
'학습 > JavaScript, TypeScript' 카테고리의 다른 글
((Typescript)) 기초 개념 (0) | 2022.10.31 |
---|---|
((실행 컨텍스트)) 실행 컨텍스트, 호이스팅, 스코프 (0) | 2022.10.24 |
((실행 컨텍스트)) 자바스크립트의 실행 컨텍스트, 호이스팅, TDZ, 스코프, 스코프 체이닝 (1) | 2022.09.26 |
데이터타입, null병합연산자, falsy값, 논리연산자 (0) | 2022.09.07 |
split() (0) | 2022.08.25 |