일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
31 |
- req.queries
- async
- CSS
- http
- res.set
- express 프로젝트 시작하기
- node.js란
- res.status
- req.params
- Axios put
- 자바스크립트
- HTML
- 웹개발
- javascript
- promise
- mongoose populate
- 프론트엔드
- mongoose find
- Axios get
- req.get
- req.body
- Axios delete
- mongoose create
- 파이썬
- res.render
- Axios post
- css 기초
- await
- mongoose delete
- mongoose update
- Today
- Total
모스카토
[JavaScript 이론] 비동기통신과 Promise 본문
1. 자바스크립트 제어 흐름
1. 동기 vs 비동기. 자바스크립트에는 두가지 제어 흐름이 있다.
동기적 제어흐름 은 현재 실행 중인 코드가 종료되기 전까지 다음 줄의 코드를 실행하지 않는 것이다.
비동기적 제어흐름 은 현재 실행 중인 코드가 있어도 병렬적으로 다른 코드를 실행하는 것이다. 비동기 작업을 기다리는 동안 메인 스레드는 다른 작업을 처리한다.
자바스크립트 엔진은 하나의 메인 스레드가 코드를 한줄씩 읽어 실행하고, 유저 이벤트를 처리하고 화면을 그리는 싱글 스레드 환경이다.
자바스크립트에서 메인 스레드를 긴 시간 점유하면 프로그램이 멈추게 할 수 있다.
따라서 자바스크립트는 동기, 비동기 차이를 알고 실행이 오래걸리는 함수는 비동기적으로 작성해야 한다.
자바스크립트에서 비동기 함수를 작성하면, 비동기 API가 엔진 외에 별도의 환경에 있는 Queue에 함수를 등록한다.
그 Queue는 task Queue에 함수의 종료 후 실행해야 한다고 알린다.
그러면 자바스크립트 메인 스레드가 이벤트 루프를 통해 task Queue를 확인하고 실행한다.
다른 멀티 스레드 언어는 비동기 함수를 만나면 새로운 스레드를 형성하고, 그 스레드는 동기적으로 작동한다.
2. 이벤트 루프
자바스크립트에서는 엔진 대신 비동기모듈을 통해 비동기 처리를 제공한다.
자바스크립트에서 비동기적으로 작동하는 함수들을 비동기 API 라고 한다.
비동기 함수들의 예시로 Web에서는 setTimeout, fetch등이 있고, node.js에서는 파일처리API, 암호화 API 등이 있다.
왼쪽의 메인 스레드는 자바스크립트 내부이고, 오른쪽의 비동기 환경은 자바스크립트 외부 이다.
비동기 환경에는 Task queue와 Job queue가 있다.
[ 비동기 처리 모델 ]
① 자바스크립트의 메인 스레드는 자바스크립트 내부에 있는 Call stack을 읽어 코드를 실행한다.
② Call stack 이 비동기 함수를 만나면, 비동기 API(비동기 함수)가 요청을 처리한다.
③ 비동기 API는 비동기 처리를 끝내면 태스크 큐에 콜백 함수를 넣는다.
④ 메인 스레드가 Call stack을 다 비우면 Event loop가Task queue에서 콜백함수를 꺼내 콜 스택에 넣는다.
* 태스크 큐는 들어온 순서대로 콜백 함수를 내보낸다.
3. Promise
Promise API는 비동기 작업의 진행, 성공, 실패 상태를 확인하여 순서를 줄 수 있는 자바스크립트 객체이고, 비동기 API 이다.
Promise의 콜백함수는 Job Queue로 들어간다. Job Queue는 Task Queue보다 우선순위가 높다.
Promise 객체는 비동기 처리 중 상태를 표현할 수 있다.
- pending상태 : 비동기 작업이 진행 중.
- settled상태 : 작업이 성공이나 실패로 끝난 후.
- 성공하면 then( ) 메소드가 실행된다.
- 실패하면 catch( ) 메소드가 실행된다.
new Promise()로 만들 수 있고, fetch() 와 같이 Promise객체를 반환하는 api를 사용하여 만들 수도 있다.
let promise = new Promise((resolve, reject) =>{
if ( Math.random() < 0.5) {
return reject('실패')
}
resolve('성공')
})
Promise 생성자는 callback 함수를 인자로 받는다.
callback함수는 resolve, reject 두 인자를 받는다. resolve 는 성공했을 때 실행할 함수, reject는 실패했을 때 실행할 함수이고, 매개변수 이름이 정해진 것은 아니다.
promise
.then(
data => {
console.log();
}
)
.catch(e => {
console.log('실패', e);
})
.finally(() => {
console.log('promise 종료');
})
위에서 생성한 Promise 객체인 promise에 then, catch, finally 메서드를 사용한다.
then( ) 에는 성공했을 때 콜백함수를 주거나, 성공했을 때 콜백함수와 실패했을 때 콜백함수를 같이 줄 수 있다.
catch( ) 에는 실패했을 때 실행할 콜백함수를 준다.
finally( ) 에는 결과와 상관없이 settled 상태이면 모두 실행할 콜백함수를 준다.
then, catch, finally에 준 함수는 위에서 promise 를 생성할 때 콜백함수에 매개변수로 준 resolve, reject 로 받아진다.
then, catch 메서드가 또 Promise 객체를 반환하는 경우 또 then, catch로 연결하여 사용할 수 있다. 이를 메서드 체이닝이라 한다.
Promise 객체는 결과 data도 리턴할 수 있고, 다음 메서드에서 그 data를 받아 쓸 수 있다.
그 전 promise 함수가 끝나야 다음 연결된 then메서드가 실행된다.
이걸 통해서 비동기적으로 코드를 실행할 순서를 줄 수 있다.
** Promise 클래스로 Promise 생성자 없이 정적으로 Promise 메서드 체인을 만들어 사용할 수 있다.
Promise.resolve(data).then(console.log('success'))
** Promise.all() 도 정적인 메서드로 Promise 의 배열을 받아서 모두 성공시 각 promise의 resolved 값을 배열로 반환한다.
하나라도 실패하면 가장 먼저 실패한 Promise의 실패 이유를 반환한다.
'엘리스 ai트랙' 카테고리의 다른 글
sql로 데이터 다루기2 (0) | 2022.02.11 |
---|---|
async / await 와 API (0) | 2022.02.10 |
sql로 데이터 다루기1 (0) | 2022.02.08 |
리눅스 기초 1 (0) | 2022.01.26 |
객체와 DOM과 이벤트 (0) | 2022.01.25 |