본문 바로가기

Javascript/Others

chatGPT와 JavaScript 공부:비동기 프로그래밍(Asynchronous Programming)

반응형

 

chatGPT와 JavaScript 공부:비동기 프로그래밍(Asynchronous Programming)
이번 포스트에서는 비동기 프로그래밍에 대해서 알아보고자 한다.
유튜브나 다른 강의에서 자주 들을 수 있었던 용어라 얼추 알고는 있지만
chatGPT가 설명해 주는 내용을 토대로 공부해 보고자 한다.
Question
자바스크립트에서 비동기 프로그래밍에 대해 자세하게 설명해줘
Answer
자바스크립트는 단일 스레드 기반의 언어입니다. 이는 한 번에 하나의 작업만 처리할 수 있다는 것을 의미합니다. 그러나 웹 브라우저 환경에서는 사용자와의 상호작용, 네트워크 요청, 타이머 등 다양한 이벤트가 동시에 발생할 수 있습니다. 이런 상황에서 비동기 프로그래밍이 중요한 역할을 합니다.

비동기 프로그래밍은 단일 스레드 언어에서도 여러 가지 작업을 동시에 처리할 수 있는 방식을 제공합니다. 이는 특정 작업이 완료될 때까지 기다리지 않고 다음 작업을 계속 진행할 수 있도록 합니다. 이렇게 함으로써 애플리케이션은 항상 반응성을 유지할 수 있습니다.
자바스크립트에서는 주로 다음 세 가지 방식을 통해 비동기 프로그래밍을 수행합니다:
콜백 함수(Callbacks)
가장 기본적인 비동기 처리 방식입니다.
콜백 함수는 특정 작업이 끝나고 나서 실행되는 함수를 의미합니다.
예를 들어, 네트워크 요청을 보내고, 요청이 끝나면 결과를 처리하는 함수를 콜백 함수로 전달할 수 있습니다.

function downloadFile(url, callback) {
    // 네트워크 요청을 흉내내는 setTimeout 함수
    setTimeout(() => {
        // 파일 다운로드가 완료되었다고 가정하고, 파일의 경로를 콜백 함수로 전달합니다.
        const filePath = 'path/to/downloaded/file';
        callback(filePath);
    }, 3000);
}

downloadFile('http://example.com/file', function(filePath) {
    console.log('File was downloaded to: ' + filePath);
});


위의 코드에서 downloadFile 함수는 파일 다운로드를 비동기적으로 처리하고, 다운로드가 완료되면 콜백 함수를 호출합니다.
프로미스(Promises)
콜백 함수의 단점을 보완한 비동기 처리 패턴입니다.
프로미스는 비동기 작업의 최종 완료 또는 실패와 그 결과 값을 나타냅니다.
프로미스는 'pending(대기)', 'fulfilled(이행)', 'rejected(거부)' 상태를 가질 수 있습니다.
프로미스는 'then'과 'catch' 메서드를 통해 비동기 작업의 성공/실패를 처리합니다.

function downloadFile(url) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            const filePath = 'path/to/downloaded/file';
            resolve(filePath);  // 다운로드가 성공적으로 완료되면 resolve 함수를 호출합니다.
        }, 3000);
    });
}

downloadFile('http://example.com/file')
    .then(filePath => {
        console.log('File was downloaded to: ' + filePath);
    })
    .catch(error => {
        console.log('Error downloading file: ' + error);
    });


위의 코드에서 downloadFile 함수는 프로미스를 반환합니다. 프로미스가 이행되면 then 메서드가 호출되고, 프로미스가 거부되면 catch 메서드가 호출됩니다.
async/await
ES2017에서 도입된 비동기 처리 문법입니다.
async/await는 프로미스를 더 편리하게 사용할 수 있도록 도와줍니다.
async 함수 안에서 await 키워드를 사용하면 프로미스가 이행될 때까지 함수의 실행을 일시적으로 멈추고, 프로미스가 이행되면 결과 값을 반환합니다.

async function downloadAndProcessFile(url) {
    try {
        const filePath = await downloadFile(url);
        console.log('File was downloaded to: ' + filePath);
        // 파일 처리 로직이 여기 이어집니다.
    } catch (error) {
        console.log('Error downloading file: ' + error);
    }
}

downloadAndProcessFile('http://example.com/file');


위의 코드에서 downloadAndProcessFile 함수는 async 함수입니다. 이 함수 내에서 await 키워드를 사용하여 프로미스가 이행될 때까지 기다립니다. 프로미스가 거부되면 try/catch 블록을 사용하여 오류를 처리합니다.
간단히 정리하자면, 자바스크립트는 단일(싱글) 스레드의 언어라서 한 번에 하나의 작업만 처리(동기 처리)가 가능하지만 비동기 처리의 경우 작업의 실행이 종료될 때까지 나머지 코드를 실행해 주는 것을 말한다.
만약 어떤 특정 데이터를 불러와야 하는데 이 데이터가 다 불러와질 때까지 마냥 기다릴 수는 없으니 데이터를 불러오는 동안 다른 코드를 작동시키는 것이다.
예로 들어서 내가 친구에게 편지를 써서 우체국을 통해 보내고 그 친구가 답장을 해준다는 상황을 가정해 보자.
동기 처리의 경우에는 편지를 보낸 후에 답장이 올 때까지 나는 아무 일도 하지 않는다.
비동기 처리의 경우 답장이 오기 전까지 마냥 기다리지 않고 다른 일을 계속하는 것이다.

즉, 비동기 처리는 결과값을 반환하기 전에 다른 작업도 수행할 수 있기 때문에 자원의 효율성을 높여준다.
그렇다면 비동기 처리에서의 단점은 무엇이 있을까?
Question
비동기 처리의 단점은?
Answer
비동기 처리는 많은 장점을 가지고 있지만, 몇 가지 주요한 문제점들이 있습니다.
콜백 지옥(Callback Hell)
비동기 처리가 콜백 함수를 사용하면서, 비동기 작업이 여러 단계로 중첩될 경우 코드가 복잡해지고 가독성이 떨어지는 문제를 일컫습니다.
이를 '콜백 지옥'이라고 부릅니다.
이 문제는 프로미스나 async/await 같은 더 현대적인 비동기 처리 패턴을 사용하면 완화할 수 있습니다.

const fs = require('fs');

fs.readFile('file1.txt', 'utf8', function(err, data1) {
    if (err) throw err;
    console.log('file1 읽기 완료!');
    fs.readFile('file2.txt', 'utf8', function(err, data2) {
        if (err) throw err;
        console.log('file2 읽기 완료!');
        fs.readFile('file3.txt', 'utf8', function(err, data3) {
            if (err) throw err;
            console.log('file3 읽기 완료!');
        });
    });
});


위 코드에서는 file1.txt, file2.txt, file3.txt 세 파일을 차례대로 읽습니다.
각 파일을 읽는 작업은 비동기적으로 처리되며, 각 작업이 완료되면 그 안에서 다음 작업을 시작합니다.
이렇게 콜백 함수가 중첩되어 발생하는 복잡성을 '콜백 지옥'이라고 부릅니다.
오류 처리
비동기 작업에서 오류가 발생하면, 이를 적절히 처리해야 합니다.
콜백 함수를 사용할 때는 오류를 전파하거나 처리하는 것이 복잡할 수 있습니다.
프로미스나 async/await는 이 문제를 'catch' 블록이나 try/catch 구문을 통해 보다 쉽게 처리할 수 있게 합니다.
순서 보장
여러 비동기 작업을 동시에 시작하면, 그 작업들이 완료되는 순서를 예측하기 어렵습니다.
이는 비동기 로직을 복잡하게 만들 수 있습니다.
특정 작업이 다른 작업보다 먼저 완료되어야 할 때는 추가적인 로직이 필요합니다.
상태 관리
비동기 작업의 상태를 추적하고 관리하는 것은 복잡한 일이 될 수 있습니다.
예를 들어, 비동기 작업이 진행 중인지, 완료되었는지, 오류가 발생했는지 등의 상태를 관리해야 할 수 있습니다.
chatGPT를 통해 비동기 처리에 관해서 간단하게 공부해 보는 시간을 가졌다.
필자처럼 취미로 코딩을 공부한다거나 시작한 지 얼마 안 된 분들은 콜백 지옥은 사실 경험해 보진 못했을 것 같다.
요즘 강의 자료들은 대부분이 async를 통한 처리로 가르쳐 주다 보니 접해볼 일이 없었던 것 같다.

정리하자면, 비동기 처리는 애플리케이션의 성능을 향상시키고, 사용자 경험을 개선시키며, 리소스를 효율적으로 활용하는 데 기여한다.
'콜백 지옥' 문제를 비롯해, 오류 처리의 어려움 등의 문제를 마주칠 수 있지만 이러한 문제들은 Promise와 async/await과 같은 기능을 활용해서 완화할 수 있다.
반응형

loading