WEB/Javascript
JS 동기와 비동기
explorer999
2024. 4. 9. 08:58
동기 / 비동기
- 동기 프로그래밍: 코드가 작성된 순서대로 위에서 아래로 실행됨. 실행되기 전에 함수나 변수 같은 것들은 최상단으로 올라감.(호이스팅)
- 자바스크립트 엔진은 한 번에 한 가지 일만 할 수 있어서 js는 기본적으로 동기적이다. ‘싱글쓰레드 언어’라는 말이 그래서 있음.
- web API는 js 엔진이 아니라 별도의 브라우저 환경에서 실행되는데, 이 환경은 여러가지 일을 동시에 할 수 있는 멀티쓰레드 환경이다. setTimeout, fetch, DOM이 대표적인 web API
- 우리는 이미 이 동기 프로그래밍에 익숙하지만 동기 프로그래밍이 불편해질 때 == 오래 걸리는 작업을 하느라고 blocking이 발생할 때이다.
- 비동기 프로그래밍: 어떤 작업이 끝날 때까지 기다리는 대신 바로 다음 작업도 동시에 실행될 수 있도록 함.
***1.***
console.log('1');
setTimeout() => {
console.log('2');
}, 3000);
--> 1이 바로 출력되고, 3000ms 뒤에 콜백함수가 실행되면서 2가 출력된다.
출력)
1
2
***2.***
setTimeout(() => {
console.log('2');
}, 3000);
console.log('1');
---> setTimeout() 함수는 실행되려면 3초가 걸리지만,
비동기적으로 수행되기 때문에 console.log(1)이 실행되는 것을 blocking하지 않음.
출력)
1
2
***3.***
console.log('시작')
setTimeout(() => {
console.log('2');
}, 3000);
console.log('1');
---> 첫줄이 먼저 실행됨과 동시에 '시작'이 출력됨.
setTimeout() 함수가 일단 호출되고 타이머가 시작됨. 실행되려면 3초가 걸리지만,
비동기적으로 수행되기 때문에 console.log(1)이 실행되는 것을 blocking하지 않음.
출력)
시작
1
2
콜백함수
- 함수는 여러가지 종류의 인자를 전달 받을 수 있는데, 또 다른 함수를 인자로 전달 받기도 한다. 다른 함수의 인자로 전달되는 함수를 콜백함수라고 함.
#메인 함수
function main(x) {
x(); #x가 sayHi라는 함수라서 이렇게 쓸 수 있음.
}
#콜백 함수
function sayHi() {
console.log("안녕");
}
main(SayHi);
출력)
안녕
(메인함수가 전달받은 콜백함수에 의해서 호출된 것이다.
call back 함수의 호출은 메인함수의 내용에 달려 있다.)
- 인자로 전달되는 함수이므로 main(sayHi()); 이렇게 하면 안 됨
function main(x) {
x();
}
1.
main(function sayHi() {
console.log('안녕');
});
2.
main(function () {
console.log('안녕');
});
3.
main(() => {
console.log('안녕');
});
이렇게 바로 메인 함수의 인자 안에서 함수를 정의하는 것은 괜찮음.
비동기 콜백
- =비동기 처리에 사용되는 콜백 함수.
- 비동기 작업은 언제 끝날지 알기 어렵고, 실행 순서도 뒤죽박죽이다.
- 비동기 작업이 모두 끝난 뒤에, 받아온 데이터를 처리하는 코드가 수행되도록 하는 후처리를 해야 한다면? 이럴 때 쓰는 게 비동기 콜백이다.
- 여러가지 비동기 작업을 연달아서 수행하면 콜백에 빠짐.
#서버에서 데이터를 받아오는 **비동기 작업**을 하는 함수...
가 끝난 뒤에 그 데이터를 후처리 해야 할 때,
콜백함수로 후처리 함수의 실행 순서를 조정할 수 있다.
function getData(callback) {
setTimeout(**() => {
console.log('서버에서 데이터를 받아왔어요');
callback(name: '상은' );
}, 2000**);
getData(() => {
console.log(data.name);
});
출력)
서버에서 데이터를 받아왔어요
상은
Promise
- 비동기 처리에 사용되는 자바 스크립트 객체.
- promise를 상자라고 한다면, 비동기 작업이 진행중일 때는 비어있다가, 작업이 완료되면 결과물로 채워진다. 성공하면 결과값이, 실패하면 작업 중 발생한 에러로 채워짐.
- promise 객체는 세 가지 상태 중 하나를 갖는다. pending(대기), fulfilled(성공), rejected(실패).
#프로미스 객체 만들기
const promise = new Promise((resolve, reject) => {
console.log('비동기 작업')
})
async, await
- async
- promise를 더 편하게 사용하기 위해서 async, await를 쓴다.
async function f() { return 1; }
- 이렇게 앞에 async가 붙은 함수는 반드시 promise를 반환한다.
- await
- let value = await promise;
- 이런 코드가 있으면.. promise가 처리될 때까지 함수 실행을 기다리게 만든다. promise가 다 처리되면 그 결과와 함께 함수 실행이 재개된다. (promise가 처리되는 동안에 다른 일들을 할 수 있도록 함)
- await은 async함수 안에서만 동작한다. (promise.then과 비슷한 기능)