JS - 동기, 비동기

김정인·2022년 12월 11일
0
post-thumbnail

📌 동기


  • 한 작업이 완전히 끝나야 다음 작업으로 넘어갑니다.

  • 순차적, 직렬적 테스크를 수행합니다.

  • JavaScript는 동기식 언어입니다. (싱글 스레드)

📌 비동기


  • 한 작업이 끝나지 않고 다음 작업으로 넘어갑니다.

  • 병렬적 테스크를 수행합니다.

🤔 그렇다면 비동기는 왜 필요할까요 ?

  • API를 호출하여 데이터를 받아온다고 가정했을 때, 비동기로 처리하지 않고 동기적으로 구성한다면 데이터를 받아오는 시간동안 기다린 다음 어떠한 로직이 실행이 될 것이고, 데이터 양이 많거나 많은 수의 API를 호출하면 속도가 느려지기 때문에 비동기적 처리가 필요합니다.

Ex) setTimeout, ajax

/* setTimeout */
console.log('1');
setTimeout(function() {
 console.log('2')
}, 3000);
console.log('3')
// 1->3->2 순으로 출력

/* ajax */
function getData() {
 var tableData;
 $.get('url', (response)=> {
  tableData = response;
 })
 // $.get()로 데이터를 요청하고 받아올 때까지 기다리지 않고 return
 return tableData;
}
console.log(tableData) // 따라서 undefined

위와 같이 비동기처리를 하면 비동기로 받아온 데이터를 처리하는데 문제가 발생할 수 있습니다. 이를 해결하기 위한 방법에는 어떤 것들이 있을까요?

비동기처리 - 1. 콜백함수로 처리하기

  • 함수 안에서 어떤 특정한 시점에 호출되는 함수입니다.

  • 아래 예시처럼 하나의 콜백 함수만 호출하는 경우 문제없지만, 계속해서 호출하면 콜백 지옥에 빠질 수 있습니다.

function getData(callback) {
 $.get('url', (response)=> {
  callback(response) // calllback 함수에 인자 response 넘겨줌
 })
}

getData(function (tableData) {
 console.log(tableData)
}) // callback

비동기처리 - 2. Promise로 처리하기

  • Promise의 상태 및 처리 흐름

    • pending(대기) : 처리가 완료되지 않은 상태, Promise객체 생성 시점부터
    • fulfilled(이행) : 처리가 성공적으로 완료된 상태 => resolve() 실행 시
    • rejected(거부) : 처리가 실패로 끝난 상태 => reject() 실행 시
    • settled : 처리 여부와 상관없이 일단 결론이 난 상태

  • Promise 메서드

    • .then() => resolve(성공 후 리턴 값)시 연결
    • .catch() => reject(실패 시 리턴 값)시 연결
    • .finally() => 성공 여부 관계없이 무조건 실행
    • .all() => 여러 개의 프로미스를 실행할 때, 모두 완료되면 실행

// 프로미스의 생성 방법은 new Promise((resolve, reject){...}) 로 생성하는 방법
function getData(callback) {
  return new Promise((resolve, reject)=> {
    $.get('~ api url 주소 ~', (response)=> {
    	if(response){
      		resolve(response); //비동기 처리 성공
        }else{
        	reject(new Error('fail')); //비동기 처리 실패
        }
    });
  });
}

// resolve 시 then 메소드, reject 시 catch 메소드의 인자로 넘어간다.
// finally()는 실패, 성공 상관 없이 무조건 실행되는 함수이다. 
getData().then((tableData)=> {
	console.log(tableData);
})
.catch((err)=> {
	console.log(err)
})
.finally((final)=> {
	console.log('finally')
});
// .all() 예제
let p1 = new Promise((resolve, reject){...})
let p2 = new Promise((resolve, reject){...})

Promise.all([p1,p2]).then( (values) =>{
	console.log('모두 완료');
})

비동기처리 - 3. async / await으로 처리

  • funcion 키워드 앞에 async를 붙여주고, 함수 내부의 promise를 반환하는 비동기 처리 함수 앞에 await을 붙여 호출합니다.

  • Promise가 처리될 때까지 기다렸다가 다음 로직을 수행합니다.

/*기본 문법
async function 함수명() {
  await 비동기_처리_메서드_명();
}
*/

function getData(callback) {
  return new Promise((resolve, reject)=> {
    $.get('~ api url 주소 ~', (response)=> {
    	resolve(response);
    });
  });
}

async function callData() {
    try{
    	let result = await getData(); // promise 결과를 기다림
    	console.log(result)
    }catch(error){
    	console.log(error)
    }
}
profile
FE 개발자

0개의 댓글