국비지원 공부 정리/JavaScript

JavaScript의 비동기 특성과 동기처리

worldstroy 2025. 3. 20. 10:21

setTimeOut(함수, 지연시간) 

설정한 delay 시간이 지난 뒤, 함수를 실행함

 

비동기 처리란?

☆특정 코드의 연산이 끝날 때까지 코드의 실행을 멈추지 않고 다음 코드를 먼저 실행하는 자바스크립트의 특성
☆서버로 데이터를 요청 시 서버가 언제 응답을 줄 지 모르는데 마냥 다른 코드를 실행 안하고 기다릴 수는 없음
☆ 비동기 처리가 아니고 동기처리라면 코드 실행하고 기다리고, 실행하고 기다리고하면 수십분이 소요될 수 있음 

 

비동기로만 처리 시 나타날 수 있는 문제점

function goMart() {
 console.log("마트에 가서 어떤 음료를 살지 고민한다.");
 }
 function pickDrink() {
 	setTimeout(function () {
     console.log("고민 끝");
     product = "제로 콜라!")
     price = 2000;
     }, 3000);
 }
 
 function pay(product, price) {
 	console.log("상품명 : ${product}, 가격 : ${price}");
 }
 
 let product;
 let price;
 goMart();
 pickDrink();
 pay(product, price);
pickDrink 함수가 실행 되기 전에 pay 함수가 실행되어서 undefined로 값이 출력되는 문제가 발생함.

 

 


 

Callback 함수

함수를 인자로 받고 다른 함수를 통해 반환될 수 있는데, 인자(매개변수)로 대입되는 함수
즉, 다른 함수가 실행을 끝낸 뒤 실행되는 함수
함수를 선언할 때는 parameter(인자, 매개변수)로 함수를 받아서 쓸 수 있다
한마디로 비동기 방식을 동기로 처리하여, 함수의 실행 순서를 개발자가 지정할 수 있게 하는 도구

 

콜백(callback) 함수의 사용 방법

 

function goMart() {
 console.log("마트에 가서 어떤 음료를 살지 고민한다.");
 }
 function pickDrink(callback) {
 	setTimeout(function () {
     console.log("고민 끝");
     product = "제로 콜라!")
     price = 2000;
     callback(product, price);
     }, 3000);
 }
 
 function pay(product, price) {
 	console.log("상품명 : ${product}, 가격 : ${price}");
 }
 
 let product;
 let price;
 goMart();
 pickDrink(pay);

 

한마디로 함수 안에서 함수를 실행 시키되, 어떤 함수를 실행시킬 지는 외부에서 정해주는 것 

 

콜백(callback) 함수를 사용할 때의 문제점

 

비동기 프로그래밍 시 발생되는 문제로 함수의 매개 변수로 넘겨지는 콜백 함수가 반복되어 들어쓰기가 너무 깊어지는 현상
가독성이 떨어지고, 코드의 수정 난이도가 올라간다.

 


 

Promise 객체

비동기 함수를 동기 처리하기 위해 만들어진 수단임은 Callback과 동일함
성공과 실패를 분리하여 반환하는 형태로 작업 완료 시 다음 작업을 연결 시켜 진행 할 수 있는 게 장점

 

 

Promise의 4가지 상태

 

Pending(대기) Promise를 수행 중인 상태
Fulfilled(이행) Promise가 Resolve 된 상태 (성공)
Rejected(거부) Promise가 지켜지지 못한 상태. Reject 된 상태 (실패)
Settled fulfilled 혹은 rejected로 결론이 난 상태
다음 함수가 실행되는 시점이라고 보면 됨

 

Promise 객체 함수의 사용법 

function promise1(flag) {
	return new Promise(function (resolve, reject) {
    	if(flag) {
        	resolve('promise 상태는 fulfiled!! then으로 연결됩니다. \n 이때의 flag가 true");
        }
        else {
        	reject('promise 상태는 rejected!! catch로 연결됩니다. \n 이때의 flag가 false");
        }
      });
    }
}

 

• Promise는 두 가지 콜백 함수를 가짐
• resolve(value) : 작업이 성공(fulfilled)한 경우, 그 결과를 value와 함께 호출
• reject(error): 에러(rejected) 발생 시 에러 객체를 나타내는 error와 함께 호출

 

 

Promise 객체의 사용법 예제

 

function goMart() {
 console.log("마트에 가서 어떤 음료를 살지 고민한다.");
 }
 function OutMart() {
 console.log("고를 물건이 없어서 마트를 나간다.");
 }
 function pickDrink() {
 	
    return new Promise(function (resolve, reject) {
    	setTimeout(function () {
     	console.log("고민 끝");
     	product = "제로 콜라!")
     	price = 2000;
     	resolve();
     	}, 3000);
    });
 }
 
 function pay(product, price) {
 	console.log("상품명 : ${product}, 가격 : ${price}");
 }
 
 let product;
 let price;
 goMart();
 pickDrink().then(pay).catch(OutMart());

 

then 메서드를 연속으로 사용해 표시하기 때문에 코드가 보기에 깔끔해짐
마지막 한번만 예외 처리하면 한꺼번에 에러 처리가 가능함

 

 


 

 

async/await

• Promise 도 chaining을 하다보면 then().then()… 처럼 꼬리를 물게 되어 코드의 가독성이 떨어질 수 있습니다.
• Promise 보다 직관적인 코드를 위해 등장한 async와 await!
• 기능이 추가된 것이 아닌, Promise를 다르게 사용하는 것

 

 

async와 await

async • 함수 앞에 붙여 Promise를 반환한다.
• 프로미스가 아닌 값을 반환해도 프로미스로 감싸서 반환한다.
• 쉽게 말해 함수의 선언 문에 붙이는 것
await • ‘기다리다’ 라는 뜻을 가진 영단어
• 프로미스 앞에 붙여 프로미스가 다 처리될 때까지 기다리는 역할을 하며 결과는 그 후에 반환한다.
• 쉽게 말해 함수의 실행 문에 붙이는 것

 

async/await 방식의 사용법

 

함수들을 실행 함수 앞에 async를 붙이고, 실행 할 함수 중에 기다려할 함수에 await를 붙임
기다릴 필요도 없는 함수에 붙이면 오히려 프로그램의 실행 속도만 지연시킬 뿐임