비동기 프로그래밍에 대해 학습하던 중 Callback, Promise, Async&await, Ajax, XMLHttpRequest, fetch API에 대한 개념을 보다 명확하게 정리하고자 작성하는 글입니다.
1편은 비동기 프로그래밍과 Callback에 대해서 알아보도록 하겠습니다.
Callback
하나의 함수가 다른 함수의 인자 값으로 전달이 되어서 그 함수에 의해 호출될 때 그 함수를 콜백 함수라고 합니다.
일단 비동기라는 개념을 제외하고 단순하게 함수를 활용하는 하나의 방식이라고 생각하면 될 것 같습니다.
콜백 함수는 비동기 프로그래밍만을 위해서가 아닌 가독성과 코드의 재사용을 위하여 사용하기도 하고 동기적인 실행을 할 수도 있습니다.
function A(B) {
console.log(1);
B();
console.log(3);
}
function B() {
console.log(2);
}
A(B);
// 결과
// 1
// 2
// 3
위와 같이 B 함수가 A 함수의 인자 값으로 전달되어서 A 함수에 의해 B가 실행됩니다.
B 자체는 콜백 함수가 아니지만 다른 함수에 호출 될 때의 B 함수를 단순히 콜백 함수라 부릅니다.
비동기 프로그래밍이란?
비동기 프로그래밍은 어떤 작업을 요청했을 때 그 작업이 종료될 때 까지 기다리지 않고 다음 작업을 수행하는 것을 의미합니다.
예를 들어 A와 B라는 함수가 있고 A 안에서 B라는 함수를 호출했다고 가정해보겠습니다.
원래대로 라면 즉, 동기 실행 방식이라면 A 함수 안에서 B 함수를 호출하는 순간 A는 다른 작업을 하지 못하고 B 함수의 작업이 끝난 뒤에서야 나머지 A 함수의 기능이 순차적으로 수행됩니다.
하지만 비동기 프로그래밍을 이용하면 A 함수 안에서 B 함수를 호출하는 순간에 A는 B 함수의 작업이 끝나지 않았더라도 다른 작업을 할 수 있습니다.
비동기는 메서드 호출시 Callback을 전달하여 작업의 완료 여부를 호출한 함수에게 답하게 됩니다.
Callback이 오기 전까지 호출한 함수 A는 신경쓰지 않고 다른 일을 할 수 있습니다.
왜 비동기 프로그래밍 방식을 사용할까요?
아래의 사진에서 보듯 비동기 방식을 이용한다면 작업의 속도가 빨라질 수 있다는 장점이 있습니다.

자바스크립트는 싱글 쓰레드 방식으로 동작합니다.
그러면 어떻게 비동기 방식은 여러가지 일을 동시에 처리할 수 있는걸까요?
바로 자바스크립트가 도는 환경에는 자바스크립트 엔진 뿐 아니라 Web API라는 것도 제공을 하기 때문입니다.

비동기 방식으로 요청을 하게 되면 Web APIs가 해당 요청을 처리하게 됩니다.
그런 다음 Callback을 받게 되면 해당 요청은 자바스크립트 엔진이 처리하는 방식입니다.
비동기 프로그래밍에서의 Callback이란?
위에서 봤던 Callback 함수는 순차적으로 실행되는 동기 방식의 단순한 코드였습니다.
비동기 프로그래밍 방식에서의 Callback도 다른 함수에 의해 호출되는 개념이므로 크게 다를바 없습니다.
브라우저에서 제공하는 Web API 중에는 setTimeout 이라는 대표적인 비동기 함수가 있습니다.
비동기 함수는 언제 코드가 실행될지 예측할 수 없는 함수입니다.
setTimeout 함수는 우리가 지정한 시간이 지나면 전달한 콜백 함수를 실행시키는 기능을 합니다.
그리고 setTimeout 함수는 두 개의 매개변수를 받는데 첫번째는 콜백 함수이고 두번째는 밀리초 단위의 시간입니다.
이 함수를 이용해 간단한 비동기 코드를 만들어볼 수 있습니다.
function A(B) {
console.log(1);
B();
console.log(3);
}
function B() {
setTimeout(function() {
console.log(2);
}, 1000);
}
A(B);
// 결과
// 1
// 3
// 2
위의 코드에서 콜백 함수인 B가 setTimeout 함수를 호출하였고 첫번째 인자로는 로그를 찍는 콜백 함수를 두번째 인자는 1초로 하여 실행되었습니다.
만약 setTimeout 함수가 비동기 함수가 아니었다면 1이 출력되고 1초가 지난 다음 2가 출력되고 3이 출력됐을 겁니다.
Callback과 setTimeout 함수를 알아보았으니 좀 더 실전적인 예제를 보겠습니다.
function findUser(id) {
let user;
setTimeout(function () {
console.log("waited 0.1 sec.");
user = {
id: id,
name: "User" + id,
email: id + "@test.com",
};
}, 100);
return user;
}
const user = findUser(1);
console.log("user:", user);
// 결과
// undefined
// waited 0.1 sec.
위의 예제는 id가 1인 user의 정보를 인자로 전달해 setTimeout에 콜백함수를 넣어 user의 정보를 넣고 user의 정보를 리턴하는 함수입니다.
결과에서 보듯이 위의 코드는 문제가 발생합니다.
setTimeout 함수는 비동기 함수 이기 때문에 해당 함수가 실행이 완료되기도 전에 user가 리턴되버립니다.
따라서 결과값은 아무것도 할당되어지지 않은 undefined가 나오게 됩니다.
이 부분은 콜백 함수를 이용하여 해결할 수 있습니다.
function findUserAndCallBack(id, cb) {
setTimeout(function () {
console.log("waited 0.1 sec.");
const user = {
id: id,
name: "User" + id,
email: id + "@test.com",
};
cb(user);
}, 100);
}
findUserAndCallBack(1, function (user) {
console.log("user:", user);
});
// 결과
// waited 0.1 sec.
// user: {id: 1, name: "User1", email: "1@test.com"}
위 코드와 차이점은 id 외에 콜백함수를 인자로 전달하여 setTimeout의 콜백함수 호출부에 넣어서 호출되도록 하는겁니다.
비동기 함수인 setTimeout의 첫번째 인자를 보면 콜백함수를 정의하고 cb라는 콜백함수도 실행하고 있습니다.
이것만 떼어놓고 본다면 비동기 함수에서 동기 처리를 하고 있다는 것을 볼 수 있습니다.
따라서 함수 호출시 0.1초 뒤에 로그가 찍히고 user에 값이 담긴 다음 cb라는 이름을 가진 콜백함수가 실행이 되어 정상적으로 출력을 하게 됩니다.
Callback 지옥이란?
Callback 지옥이란 Callback 함수 안에 또 다른 Callback 함수가 여러개 있는 것으로 위의 예제에도 SetTimeout의 인자인 Callback 함수 안에 cb라는 Callback 함수를 호출하는 것을 볼 수 있습니다.
cb함수 안에 또 다른 Callback 함수를 넣을 수 있고 그렇게 된다면 3개 이상만 되어도 난해한 코드가 되어버릴 것입니다.
아래와 같은 작업을 보통 Callback 지옥이라고 합니다.
timer(1000, function(){
console.log('작업');
timer(1000, function() {
console.log('작업');
timer(1000, function() {
console.log('작업');
});
});
});
그러한 지옥에서 탈출시켜주는 것이 Promise와 Async/Await 입니다.
그러면 Promise와 Async/Await는 지옥에서 어떻게 탈출 시켜주는지, 그리고 Ajax는 무엇이고 Fetch API는 무엇인지 추후에 알아보도록 하겠습니다.
다음글
비동기 프로그래밍(Callback, Promise, Async&await)과 AJAX - 2
참고
https://developer.mozilla.org/ko/docs/Web/API/setTimeout
https://www.youtube.com/watch?v=TAyLeIj1hMc&t=601s
https://www.youtube.com/watch?v=s1vpVCrT8f4&t=533s
https://www.daleseo.com/js-async-callback/
'JavaScript' 카테고리의 다른 글
| 비동기 프로그래밍(Callback, Promise, Async&await)과 AJAX - 4 (0) | 2022.03.20 |
|---|---|
| 비동기 프로그래밍(Callback, Promise, Async&await)과 AJAX - 3 (0) | 2022.03.19 |
| 비동기 프로그래밍(Callback, Promise, Async&await)과 AJAX - 2 (0) | 2022.03.18 |
| Webpack이란? (0) | 2021.09.14 |