티스토리 뷰

JavaScript

JS - 동기, 비동기

김관장 2022. 2. 19. 16:03

1. 동기

[ 개념 ]

  • 한 작업이 완전히 끝나야 다음 작업으로 넘어간다.
  • 순차적, 직렬적 테스크를 수행한다.

2. 비동기

[ 개념 ]

  • 한 작업이 끝나지 않고 다음 작업으로 넘어간다.
  • 병렬적 테스크를 수행한다.

[ 왜 필요할까? ]

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

예제 ) setTimeout / ajax

console.log('1');
setTimeout(function() {
 console.log('2')
}, 3000);
console.log('3')
// 1->3->2 순으로 출력
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로 처리

*기본적으로 Callback과 하는 일이 같다.

// 프로미스의 생성 방법은 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')
});

*Promise의 상태 및 처리 흐름

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

프로미스 처리 흐름 - 출처 : MDN

*Promise 메서드

  • .then() => Resolve(성공 후 리턴 값) 연결 
  • .catch() => Reject(실패 시 리턴 값)
  • .finally() => 성공 여부 관계없이 무조건 실행
  • .all() => 여러 개의 프로미스가 모두 완료될 때 실행
// .all() 예제
let p1 = new Promise((resolve, reject){...})
let p2 = new Promise((resolve, reject){...})

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

 

3. async와 await으로 처리

//기본 문법
//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(); // 프로미스 결과를 기다림
    	console.log(result)
    }catch(error){
    	console.log(error)
    }
}

'JavaScript' 카테고리의 다른 글

JS - JSX?  (0) 2022.03.31
JS - Map() 과 Set()  (0) 2022.03.02
JS - 불변성(ps. Immutable)  (0) 2022.02.24
JS - 함수 (일반, 리터럴-익명)  (3) 2022.02.21
JS - 배열 메소드 (forEach, some, every, map, reduce, filter)  (4) 2022.02.21
댓글