코드 중에서 실행하는 데 비교적 오래 걸리는 것들이 존재할 수 있다.
예를 들어 코드로 웹 리퀘스트(Web Request)를 보낼 수 있는데
response = sendRequest('https://www.naver.com')
이 작업이 완료되려면 인터넷을 통해 리퀘스트(Request)가 서버까지 전달되어야 하고
서버가 리퀘스트를 처리하고, response가 다시 컴퓨터까지 전달되어야 한다.
물론 요즘 인터넷 속도도 빠르고 대체로 컴퓨터 따른 성능도 높지만
단순한 연산을 하는 것에 비교하면 몇천 배 또는 그 이상의 시간이 걸린다.
그런데 코드로 리퀘스트를 보내고 리스폰스를 기다리는 동안에는 컴퓨터가 따로 하는 일 없이
리스폰스를 기다리기만 하는데,
기다리는 시간 동안 수천 개의 연산을 할 수 있을 텐데
마냥 기다리고만 있는 것은 별로 효율적이지 않다.
효율적인 프로그램은 오랜 시간 기다려야 할 때
다른 일을 먼저 하고 있다가
기다리던 작업이 완료되면 다시 그 일로 돌아갈 것이다.
이것이 바로 비동기 프로그래밍의 핵심이다.
비동기 프로그래밍은 주어진 코드를 꼭 순서대로 실행하는 것이 아니라
오래 기다려야 하는 작업이 있으면 다음 작업을 먼저 처리하고
나중에 처리하던 작업으로 다시 돌아와 마무리하는 방식이다.
자바스크립트는 비동기 프로그램을 짜기 위한 다양한 문법과 툴을 제공하기 때문에
사용 방법만 알면 쉽게 구현할 수 있다.
원래 자바스크립트는 웹에 사용하기 위해 만들어진 언어이고
웹 개발은 위와 같이 리퀘스트를 보내거나
사용자의 상호작용을 기다려야 하는 일이 많기 때문에
비동기 프로그래밍이 많이 쓰이는 편이다.
또한 자바스크립트의 리액트(React)나 익스프레스(Express) 같은 기술도
비동기 프로그래밍 개념이 사용되며
다양한 자바스크립트 기술을 알기위함과 사용할 계획이라면
비동기 프로그래밍의 개념을 이해하고 넘어가야한다.
비동기 프로그래밍을 하려면 꼭 알아야하는 것은
크게 콜백(Callback), 프로미스(Promise) 두 가지가 있다.
먼저 콜백함수부터 살펴보자
Callback
▶package.json, main.js 파일
// package.json
{
"type": "module"
}
// main.js
function sayHello() {
console.log('Hello World!');
}
function sayGoodbye() {
console.log('Goodbye World!');
}
function printMessage(func) {
console.log('Printing message...');
func();
}
콜백은 어떤 함수의 아규먼트로 또 다른 함수를 전달하는 것을 의미한다.
즉 아규먼트로 전달되는 함수를 콜백 함수라고 한다.
다음 콜백의 다양한 예시를 보며 어떻게 사용되는가, 어떤 개념인지 살펴보자
package.json 파일을 열어보면 import, export 같은
ES Module 문법을 사용하기 위해 "tyle" : "module"로 설정하고
main.js 파일에는 간단한 몇 개의 함수가 정의 되어있다.
함수들을 보면 'Hello World"와 "Goodbye World"를 출력하는 함수들이고
세 번째 함수 printMessage는 어떤 함수(func)를 파라미터로 받아서
"Printing message"를 출력하고 파라미터로 받은 함수(func)를 호출하는 함수이다.
다음과 같이 코드를 작성해보자
printMessage(sayHello);
여기서 sayHello 뒤에 괄호를 쓰지 않는 것이 중요한데
sayHello를 호출하는 것이 아닌 그냥 아규먼트로 전달하는 것이기 때문이다.
결과를 보면 Printing message가 출력되고
sayHello가 본문 안에서 실행돼서 그 뒤에 "Hello World"가 출력되는 것을 화인 할 수 있다.
만약에 sayHello가 아닌 sayGoodbye를 넣으면
그 뒤에 "Goodbay World" 가 출력 될 것이다.
이처럼 SayHello나 sayGoodbye에서
다른 함수의 아규먼트로 전달되는 함수를 콜백(Callback)이라고 부른다.
위와 같이 간단한 콜백은 Arrow Function을 사용할 수도 있다.
function sayHello() {
console.log('Hello World!');
}
function sayGoodbye() {
console.log('Goodbye World!');
}
function printMessage(func) {
console.log('Printing message...');
func();
}
// printMessage(sayHello);
printMessage(()=>{
console.log('Hello World!');
})
조금 더 복잡한 예시를 살펴보자
sayHello랑 sayGoodbye, printMessage 함수에 name 파라미터를 입력했다.
printMessage 함수는 안에서 func 콜백을 호출할 때 name을 넘기도록 하였고
function sayHello(name) {
console.log(`Hello ${name}`);
}
function sayGoodbye(name) {
console.log(`Goodbye ${name}`);
}
function printMessage(func,name) {
console.log('Printing message...');
func(name);
}
printMessage(sayHello, '섭이')
printMessage의 func는 sayHello, name은 '섭이'가 되므로
최종 출력 결과는 'printing message... /n Hello 섭이 '가 될 것이다.
이렇게 콜백은 파라미터를 받을 수 있고
파라미터를 받는 경우 바깥 함수 안에서
파라미터를 채워서 콜백을 실행해 주는 것이다.
똑같이, 화살표 함수로 다음과 같이 바꿀 수 있다.
function sayHello(name) {
console.log(`Hello ${name}`);
}
function sayGoodbye(name) {
console.log(`Goodbye ${name}`);
}
function printMessage(func,name) {
console.log('Printing message...');
func(name);
}
// printMessage(sayHello, '섭이')
printMessage((name) => {
console.log(`Goodbye ${name}`);
},'섭이')
이렇게 간단한 콜백에는 화살표 함수를 많이 사용한다.
여기까지 정리하자면..
어떤 함수의 아규먼트로 전달되는 함수를 콜백(Callback) 이라고 한다.
함수를 선언한 다음에 전달할 수도 있고 화살표 함수를 사용해서 바로 전달 할 수 도 있으며
상황에 따라 파라미터를 받는 콜백도 전달 할 수 도 있고
콜백을 전달하면 바깥 함수 안에서 콜백을 실행 해준다.
여기서 복습 겸 문제를 하나 풀어보자
function TestCallback(array, callback) {
for (let elt of array) {
callback(elt);
}
}
const words = ['JavaScript', 'Java', 'Python'];
// 배열의 요소를 출력한다 - Arrow Function 사용
TestCallback(words, );
// 배열의 요소를 대문자로 출력하고 function 키워드로 함수를 선언하고 콜백으로 전달한다.
TestCallback(words, );
문제를 간단하게 요약해보자면
- 주어진 TestCallback() 함수는 배열의 요소를 하나씩 순회하며, 각 요소를 callback 함수로 처리한다.
- 이 forEach 함수를 활용해 두 가지 작업을 해야 한다.
- Arrow Function으로 배열의 요소를 출력.
- function 키워드로 정의된 함수로 배열의 요소를 대문자로 변환하여 출력.
function TestCallback(array, callback) {
for (let elt of array) {
callback(elt);
}
}
TestCallback은 배열 array를 순회하며 배열의 각 요소를 callback 함수에 전달하고 있다.
for...of문을 사용하여 배열의 요소를 하나씩 가져오고 있고
가져온 각 요소를 callback(elt)로 처리하고 있다.
그렇다면 화살표 함수로 배열의 요소를 출력하기 위해선
TestCallback 함수에 화살표 함수를 전달하고
callback 역할을 하는 화살표 함수가 필요하므로
다음과 같이 코드를 작성할 수 있다.
// 배열의 요소를 출력한다 - Arrow Function 사용
TestCallback(words, (element) => console.log(element));
이렇게 배열의 요소 (element)를 단순히 출력하여
JavaScript, Java, Python을 차례로 출력할 것이다.
그 다음 문제로,
배열의 요소를 대문자로 출력하기 위해 toUpperCase() 메소드를 사용할 것이고
TestCallback 함수에 일반 함수(function 키워드로 정의된 함수)를 전달하여
callback 역할을 하는 함수는 각 요소를 받아서 대문자 변환 메소드를 사용해 출력할 수 있다.
// 배열의 요소를 대문자로 출력하고 function 키워드로 함수를 선언하고 콜백으로 전달한다.
TestCallback(words, function(element){
console.log(element).toUpperCase());
});
이렇게 각 배열의 요소는 대문자로 변환되어 다음과 같이 출력된다.
이렇게 콜백 함수를 사용해봤다.
'JS' 카테고리의 다른 글
(3) Asynchronous JavaScript - 비동기 함수들의 예시 (0) | 2024.12.31 |
---|---|
(2) Asynchronous JavaScript - 콜백(callback)과 비동기 함수(async function) (0) | 2024.12.30 |
(9) JavaScript Module - 유용한 npm 커맨드 (0) | 2024.12.26 |
(8) JavaScript Module - package-lock.json (0) | 2024.12.25 |
(7) JavaScript Module - Semantic Version (시멘틱 버전) (0) | 2024.12.25 |