[TIL / Asyncronous & callback]

G·2021년 4월 27일
0
post-thumbnail

비동기(Async)? 동기(Sync)?

자바스크립트에서 비동기라는것은 어떤 특정한 코드가 실행될때 현재 코드의 연산이 끝날때까지 기다리는게 아니라
그 다음 실행할 코드가 있을경우, 기다리지않고 다음 코드를 먼저 실행하는것을 말한다.

반대말인 syncronous와는 다른점이 있다.
비동기의 특성과는 다르게 syncronous는 특정코드가 실행되서 완료될때까지 기다리고, 완료가 되면 그 다음 코드가
실행되는 식이다.

실생활로 예를들어보면, 카페를 가서 커피를 시킨다고 생각해보자!
보통 우리는 커피를 시키고 진동벨을 받아와 기다렸다가 내가 주문한 커피가 나오면 받으러 간다.
내가 주문한 커피가 만들어지기 시작하고, 동시에 그 다음 손님의 주문을 받는다.(이런방식이 비동기적 방식!)
(웹상에서도 보면 우리가 유튜브를 볼때, 영상로딩이 진행된다고 하더라도 다른 버튼들은 활성화가 되있어서 누를수가 있다.)

하지만, 동기적 관점으로 보면 내가 커피를 주문하면 직원은 주문을 받고 원두를 갈고 커피를 내리고 컵에 따르고 이런방식을 다 하고나서 나에게 커피를 주면 그제서야 다음 사람의 주문을 받고 또 이런작업을 반복한다.(동기적 방식)

callback 함수

위에서 카페로 비동기를 설명했는데, 내가 배운것중에 이와 같은 동작을 하는 함수가 있다.
바로 콜백(callback)함수이다.
비동기처리를 기본으로 한다. 하지만, 특정 로직에서는 순차적인 처리가 필요할 수 있기 때문에 동기처리를 위해 쓰이기도 한다.

callback함수 템플릿

function myFunc(a, b, callback) {
	// 처리할 내용들
    callback()
}

callback함수를 이용한 비동기처리의 예

console.log('유비: 관우야 아메리카노 한잔 사줘.')
setTimeout(function(){
	console.log('점원(장비): 주문하신 아메리카노 한잔 나왔습니다!')
}, 5000)
console.log('관우: 아메리카노 한잔 주문할게요.')

setTimeout()은 비동기 방식으로 실행되기때문에 유비, 관우
그리고 설정한 시간인 5초 후에 점원인 장비가 대답하는걸 볼 수 있다.

순차적으로 실행되는 함수

function coffee(item, price, quantity) {
    console.log(item + "를(을)" + quantity + "잔 주문하였습니다.")
    console.log("값을 지불해주세요.")
    let resultPr = price*quantity
    return resultPr
}
function pay(result) {
  if(result !== undefined) {
    console.log(result + "원을 지불하였습니다.")
  }
}
let bill = coffee('아메리카노', 1500, 5)
pay(bill)

잘못 처리된 비동기 방식

위에서 사용한 setTimeout()을 사용해보자.

function coffee(item, price, quantity) {
    console.log(item + "를(을)" + quantity + "잔 주문하였습니다.")
    setTimeout(function() {
    	console.log("값을 지불해주세요.")
    	let resultPr = price*quantity
    	return resultPr
    }, 5000)
}
function pay(result) {
    console.log(result + "원을 지불하였습니다.")
}
let bill = coffee('아메리카노', 1500, 5)
pay(bill)

기존의 결과값과는 다르게 내가 원하는 값이 나오지 않고 순서마저 뒤죽박죽이 된다.
이런 결과가 나오는 이유는 내가 사용한 setTimeout 함수는 비동기 방식의 대표적인 예로 순차적인 실행을 보장하지않는다.
5초가 지나고 setTimeout 내부의 console.log가 출력되는게 아니고, 
setTimeout을 호출하자마다 다음 출력물이(undefined원을 지불하였습니다.) 출력된다. 
undefined인 이유는 bill 변수에 아무값도 없기때문이다.

callback을 사용해서 문제점 해결해보기

function coffee(item, price, quantity, callback) {
    console.log(item + "를(을)" + quantity + "잔 주문하였습니다.")
    setTimeout(function() {
    	console.log("값을 지불해주세요.")
    	let resultPr = price*quantity
    	callback(resultPr)
    }, 5000)
}
function pay(result) {
    console.log(result + "원을 지불하였습니다.")
}
coffee('아메리카노', 1500, 5, pay)

값을 지불해주세요 출력 이후 콜백함수를 실행시키는 과정.
(아메리카노를 5잔 주문하였습니다.) 이후 setTimeout
함수 내부에 있는 callback함수가 실행된다.
이때 인자로 받은 callback은 pay함수이며, 
내가 지정한 시간 5초가 지나면 값을 지불해달라는 메시지와 
7500원이 지불되었다는 메시지가 동시에 뜨게 되어 문제점이 해결되는걸 볼 수 있다!!

callback 함수는 항상 좋은가??

callback함수는 위의 예제들과 같이 비동기로 작성된 함수들을 동기적으로도 처리할 수 있고, 실제로 많이 쓰이고 있다고 한다.
하지만 콜백함수를 한번, 두번.. .. 계속 쓰다보면 callback hell에 빠질수도 있으므로 상황에 따라 적절히 써야한다.(가독성면에서도 효율이 엄청나게 떨어진다..)
하지만 이를 위해 생긴게 있으니 바로 promise와 async/await 이다!!
다음번 TIL은 이 두가지를 정리해야겠다.

console창의 undefined??

계속 undefined가 붙길래 뭐지뭐지 하고 찾아보았다.
자바스크립트는 함수안에서 return하는 값이 없으면 호출할때 undefined가 console.log에 찍혀서 반환된다고 한다!!
출처: https://jsdev.kr/t/undefined/3985

profile
Drarreg

0개의 댓글