Asynchronous(callback, promise, async)

ou·2024년 1월 22일
0

basic

목록 보기
17/24

callback

다른 함수에 인수로 전달되어 나중에 실행되는 함수

설명에서 볼 수 있듯이 callback이 비동기를 처리하는 방법을 칭하는 것은 아니다. 다만 기존에 비동기 처리에 많이 쓰이다보니 비동기에 대해 설명하려면 콜백이 빠질 수 없게 된 것.

먼저 callback에 대해서 간단히 알아보자
함수도 객체이므로 함수의 파라미터로 전달될 수 있다.
아래 예시를 보자

function sum(a, b, callback){ //세번째 매개변수로 함수를 받는다.
	const result = a+b;
  	callback(result);
}
function print(str){
	console.log(str);
}
sum(1,2,print) // 3 

sum은 세번째 파라미터로 function을 받으려하고 있고 함수호출 단계에서 매개변수로 print라는 함수를 매개변수로 넣어줬다.
이 때 print를 callback 함수라 칭한다.

즉, 함수의 파라미터로 전달되는 함수

그렇다면 callback 함수를 어떻게 비동기 처리에 사용한다는걸까?
아래 예시를 보자

function first(callback){ //함수 선언 시 함수를 매개변수로 받으려함
	let value;
	setTimeout(()=>{
    	value = 1;
      	callback(1);
    },3000)
}
//호출 - 매개변수로 함수를 넘겨줌
first(function(val){
	console.log(val); // 1
})

하지만 만약 first에서 val을 console.log찍는데 그치지 않고, 제2, 3의 함수로 연달아서 계속 넘겨야한다면??
아래와 같은 모양이 될 것 이다.

function first(callback){
	let value;
	setTimeout(()=>{
      	console.log("first")
    	value = 1;
      	callback(value);
    },1000)
}
function second(value, callback){
	setTimeout(()=>{
      	console.log("second")
    	value += 1;
      	callback(value);
    },1000)
}
function third(value, callback){
	setTimeout(()=>{
      	console.log("third")
    	value += 1;
      	callback(value);
    },1000)
}
//호출
first(function(val){
  second(val, function(val){
  	third(val, function(val){
    	console.log(val);
    })
  })
})

위 예시에서는 thrid까지 있었지만 여러 함수가 연달아 계속되고 에러 처리에 대한 로직도 들어간다면 코드의 가독성이 떨어질 것이다.

그래서 후에 기술할 promise와 async&await가 등장했다.

Promise

비동기 작업의 결과를 나타내는 객체로 Javascript 공식 객체
반면 callback은 일종의 패턴을 칭하던 암묵적인 명칭.

//new 생성자로 생성하며 매개변수로 executor라는 함수를 받음
new Promise(function(resolve, reject){
  //resolve() 성공 시 value 반환
  //reject() 실패 시 error 반환
})

Promise는 네 가지 상태가 있음. 종료된 후를 나타내는 settled는 제외하고 아래 그림을 보자.
Promise가 생성되면 Pending 상태이며 resolve, reject가 호출 전까지 pending이다.
성공적으로 실행하면 fulfilled, 실패하면 rejected 상태로 변한다.

//성공 (resolve)
const result = new Promise(function(resolve, reject){
	resolve("success")
})
console.log(result); //fulfilled 프로미스 객체. //success라는 값이 오는 것이 아니다.
//값을 받는 법은 곧 기술하겠다.
//실패 (reject)
const result = new Promise(function(resolve, reject){
	reject("fail")
})
console.log(result); //rejected 프로미스 객체.

위 예시에서 result는 프로미스 객체로 "sucess""fail" 값을 갖고 있지 않다고 했다.
그럼 결과 값을 받기 위해서는 어떻게 해야할까?

then, catch, finally

//then
const result = new Promise(function(resolve, reject){
	resolve("success")
})
result.then(function(resolve_value){
  	console.log(resolve_value); //success
})

//catch - 새로운 script 시작이라고 간주
const result = new Promise(function(resolve, reject){
	reject("fail")
})
result.then(function(resolve_value){
  	console.log(resolve_value); //코드 실행이 여기로 오지 않음
})
.catch(function(reject_value){ //실패했으므로 catch구문으로 감
  	console.log(reject_value); //fail
})

//then에서 catch까지 가능하다.
//then에 두번째 매개변수로 catch에 들어가는 함수를 넣으면된다. -
//하지만 일반적으로 이렇게 쓰지 않으니 알고 있으면 됨
const result = new Promise(function(resolve, reject){
	reject("fail")
})
result.then(function(resolve_value){
  	console.log(resolve_value); //코드 실행이 여기로 오지 않음
}, function(reject_value){ //실패했으므로 catch구문으로 감
  	console.log(reject_value); //fail
})

//finally Promise가 성공,실패했든 마무리되면 실행

async & await

callback 지옥에서 벗어나려 Promise를 내놓았더니
then도 반복되니 체인처럼 늘어지더라
그래서 async, await가 등장

function 앞에 async를 붙이면 암시적으로 Promise를 반환하게 된다.

async function ya(){
	return 1;
}
ya().then((res)=>{
	console.log(res) // 1
})

promise에서는 reject로 실패를 반환할 수 있었는데, async에서는 어떻게 에러를 반환할까?
throw를 쓴다.

async function ya(){
	throw new Error("fail");
}
ya().then((res)=>{
	console.log(res)
})
//이렇게하면 Uncaught error라고 뜬다. 
//Uncaught - 잡히지 않은.
//그렇다 catch를 이용해 error를 잡아줘야하고
//에러 발생 시 어떻게 처리할지 분기 할 수 있다.
async function ya(){
	throw new Error("fail");
}
ya().then((res)=>{
	console.log(res)
})
.catch((error)=>{
  console.log(error);
  //에러 발생 시 처리할 코드
})

참고자료
https://gruuuuu.github.io/javascript/async-js/ (⭐⭐)
https://juicyjerry.tistory.com/entry/async-%EC%98%88%EC%99%B8%EC%B2%98%EB%A6%AC%EC%9D%98-%EA%B9%8C%EB%8B%A4%EB%A1%9C%EC%9A%B4%EC%A0%90#google_vignette
https://gruuuuu.github.io/javascript/asyncawait/
https://inpa.tistory.com/entry/%F0%9F%8C%90-js-async

profile
경험을 현명하게 사용한다면, 어떤 일도 시간 낭비는 아니다.

0개의 댓글

관련 채용 정보