비동기란?
자바스크립트에서 비동기 작업은 특정 작업을 수행하고 결과를 반환하기 전에 다른 작업을 수행할 수 있는 방법이다. 이를 통해 애플리케이션의 반응성을 높일 수 있다.
예를 들어, 웹 애플리케이션에서 서버 쪽 데이터가 필요할 때는 Ajax 기법을 사용해 서버의 API를 호출함으로써 데이터를 수신한다. 이렇게 서버의 API를 사용해야할 때는 네트워크 송수신 과정에서 시간이 걸리기 때문에 작업이 즉시 처리되는 것이 아니라, 응답을 받을 때까지 기다렸다가 전달받은 응답 데이터를 처리한다. 이 과정에서 해당 작업을 비동기적으로 처리하게 된다.
만약 작업을 동기적으로 처리한다면 요청이 끝날 때까지 기다리는 동안 중지상태가 되어야 하기 때문에 다른 작업을 할 수 없다. 하지만 이를 비동기적으로 처리한다면 웹 애플리케이션이 멈추지 않기 때문에 동시에 여러 가지 요청을 처리할 수 있고, 기다리는 과정에서 다른 함수도 호출할 수 있다.
비동기 작업은 주로 콜백 함수, 프로미스, async/await와 같은 메커니즘을 사용하여 처리된다.
콜백 함수
자바스크립트에서 비동기 작업을 할 때 가장 흔히 사용되는 방법은 콜백함수를 사용하는 것이다. 콜백함수는 다른 함수에 전달되는 함수로, 해당 함수가 완료되면 호출된다. 이를 통해 비동기 작업의 결과를 처리할 수 있다.
예를 들어, XMLHttpRequest 객체를 사용하여 서버에서 데이터를 가져오는 경우, 콜백 함수를 사용하여 데이터를 처리한다. XMLHttpRequest 객체의 open() 및 send() 메서드를 호출하여 서버에 데이터 요청을 보내고, 서버에서 응답이 완료되면 콜백 함수가 호출되며, 이 콜백 함수를 사용하여 응답 데이터를 처리하고 애플리케이션에서 사용할 수 있는 형태로 변환한다.
콜백 함수는 다른 함수에서 호출될 때 인수로 전달된다. 이 인수는 함수 내에서 콜백 함수를 호출하는데 사용되며, 콜백 함수는 일반적으로 함수의 마지막 인수로 전달된다.
콜백 함수는 함수를 실행하는 동안 호출되기 때문에 비동기 작업의 결과를 처리하는데 유용합니다. 콜백 함수를 사용하면 비동기 코드의 흐름을 제어할 수 있으며, 비동기 작업이 완료될 때까지 코드 실행을 일시 중지할 필요가 없습니다.
function sayHello(name, callback) {
console.log("Hello, " + name);
callback();
}
function sayGoodbye() {
console.log("Goodbye!");
}
setTimeout(function() {
sayHello("John", sayGoodbye);
}, 1000);
위 코드는 콜백 함수의 예시 코드이다. setTimeout() 함수를 사용해 1초 후에 콜백 함수를 호출한다.
위 코드에서 sayHello 함수는 첫 번째 인수로 이름을 받으며, 두 번째 인수로 콜백 함수를 받는다. sayHello 함수는 이름을 출력한 후, 콜백 함수를 호출한다. sayGoodbye 함수는 간단하게 "Goodbye!"를 출력하는 함수이다.
setTimeout 함수는 1초 후에 첫 번째 인수로 전달된 함수를 실행한다. 이 함수는 sayHello 함수를 호출하며, 두 번째 인수로 sayGoodbye 함수를 전달한다. 따라서 sayGoodbye 함수는 sayHello 함수가 실행된 후에 1초 후에 실행된다. 이를 통해 콜백 함수를 사용하여 비동기 작업을 처리하는 방법을 볼 수 있다.
하지만, 콜백 함수는 콜백 지옥(callback hell)이라는 문제점이 있다. 이는 콜백 함수를 중첩하여 사용할 때 발생하는 코드의 가독성과 유지보수성을 저해하는 문제이며, 이를 해결하기 위해 프로미스나 async/await과 같은 더 나은 비동기 코드 처리 방법을 사용할 수 있다.
Promise
Promise는 자바스크립트에서 비동기 작업을 처리하는 객체이다. Promise는 비동기 작업의 성공 또는 실패에 대한 결과를 나타내는 객체로, 이를 통해 비동기 작업의 결과를 처리할 수 있다.
Promise는 세 가지 상태를 가질 수 있다. 처음에는 Pending(대기)상태이며, 작업이 성공적으로 완료되면 Fulfilled(이행)상태, 실패하면 Rejected(거부)상태가 된다. Promise는 이러한 상태를 변경할 수 있는 메서드를 제공하며, 작업이 완료될 때 상태를 변경한다.
Promise 객체를 생성하면, 이 객체는 비동기 작업을 수행하며 결과를 반환하는 함수를 전달한다. 이 함수는 두 개의 인수를 받는다. 첫 번째 인수는 작업이 성공했을 때 반환되는 값이며, 두 번째 인수는 작업이 실패했을 때 반환되는 오류 객체이다.
Promise 객체는 then() 메서드를 사용하여 작업이 성공적으로 완료되었을 때 처리할 함수를 등록할 수 있다. catch() 메서드를 사용하여 작업이 실패했을 때 처리할 함수를 등록할 수도 있다.
function getDataFromServer() {
return new Promise(function(resolve, reject) {
// 비동기 작업 수행
setTimeout(function() {
const data = { name: "John", age: 30 };
if (data) {
resolve(data); // 성공적으로 작업을 수행하면 resolve 호출
} else {
reject("Error occurred"); // 작업이 실패하면 reject 호출
}
}, 1000);
});
}
// Promise 객체 사용
getDataFromServer()
.then(function(data) {
console.log("Data: ", data); // 성공적으로 수행했을 때 실행될 코드
})
.catch(function(error) {
console.error(error); // 실패했을 때 실행될 코드
});
위 코드에서, getDataFromServer 함수는 Promise 객체를 반환한다. 이 함수는 비동기 작업을 수행하고, 작업이 성공적으로 완료되면 resolve 메서드를 호출하여 데이터를 반환하고, 작업이 실패하면 reject 메서드를 호출해서 오류를 반환한다.
getDataFromServer 함수가 반환한 Promise 객체는 then() 및 catch() 메서드를 사용하여 처리된다. then() 메서드는 작업이 성공적으로 완료되었을 때 호출된다. catch() 메서드는 작업이 실패했을 때 호출된다. 이를 통해 비동기 작업의 결과를 처리하는 방법을 볼 수 있다. 여러 작업을 연달아 처리한다고 해서 함수를 여러번 감싸는 것이 아니라, .then을 사용해 그 다음 작업을 설정하기 때문에 콜백 지옥이 형성되지 않는다.
async / await
async / await은 자바스크립트에서 비동기 작업을 처리하는 방법 중 하나이다. 이전에는 콜백 함수와 Promise를 사용하여 비동기 작업을 처리했지만, async / await를 사용하면 코드가 더 간결하고 읽기 쉬워진다.
async / await는 async 함수와 await 연산자를 사용하여 구현된다. async 함수는 비동기 작업을 처리하는 함수로, 내부에서 await 연산자를 사용하여 Promise를 처리한다. await 연산자는 Promise가 완료될 때까지 함수의 실행을 일시 중지하며, Promise가 완료되면 그 결과를 반환한다.
async 함수를 호출하면 해당 함수가 Promise 객체를 반환한다. 이를 통해 then() 메서드와 catch() 메서드를 사용하여 비동기 작업의 결과를 처리할 수 있다.
위의 Promise의 예시 코드를 async / await을 사용해서 작성할 수 있다.
function getDataFromServer() {
return new Promise(function(resolve, reject) {
// 비동기 작업 수행
setTimeout(function() {
const data = { name: "John", age: 30 };
if (data) {
resolve(data); // 성공적으로 작업을 수행하면 resolve 호출
} else {
reject("Error occurred"); // 작업이 실패하면 reject 호출
}
}, 1000);
});
}
async function fetchData() {
try {
const data = await getDataFromServer();
console.log("Data: ", data); // 성공적으로 수행했을 때 실행될 코드
} catch (error) {
console.error(error); // 실패했을 때 실행될 코드
}
}
fetchData();
위의 코드에서, fetchData 함수는 async 함수로 정의되어 있다. 이 함수 내부에서 getDataFromServer 함수를 호출하고, await 연산자를 사용하여 Promise 객체를 처리한다. Promise 객체가 resolve되면 데이터를 data 변수에 저장하고, 이를 콘솔에 출력한다. Promise 객체가 reject되면 에러를 콘솔에 출력한다.
fetchData 함수를 호출하면 해당 함수가 Promise 객체를 반환한다. 이를 통해 then() 메서드와 catch() 메서드를 사용하여 비동기 작업의 결과를 처리할 수 있다. 이를 통해 async / await를 사용하여 비동기 작업을 처리하는 방법을 볼 수 있다.
'WEB' 카테고리의 다른 글
리덕스 이해하기 [react/redux/typescript] (2) | 2023.03.21 |
---|---|
타입스크립트 핸드북 훑어보기 [2. Everyday Types] (0) | 2023.03.11 |
타입스크립트 핸드북 훑어보기 [1. The Basics] (0) | 2023.03.10 |
타입스크립트 문서 훑어보기 (0) | 2023.03.09 |
[HTTP - 02] HTTP 트랜잭션 / TCP (0) | 2023.02.23 |