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과 비슷한 기능)