[JS] 비동기식 JS(JavaScript)

hye0n.gyu·2024년 8월 18일
0

JS

목록 보기
12/13
post-thumbnail

⭐ 콜 스택(Call Stack)

콜스택(Call Stack) 은 프로그래밍 언어에서 함수 호출을 관리하는 메모리 구조이다. 주로 자바스크립트, 파이썬, 자바 등 다양한 프로그래밍 언어에서 사용된다.
이름에서 알 수 있듯 Stack 구조이다.

Stack 구조는 한쪽 끝에서만 데이터를 넣고 뺄 수 있는 제한적으로 접근할 수 있는 LIFO(Last In First Out, 후입선출) 구조로 나중에 들어온 데이터를 먼저 뺀다.

✔ 콜 스택(Call Stack) 예제

function callStackEx(a, b){
    return fn2(a,b) + fn2(b,a)
}

function fn2(a,b){ // a*b
    a = a*b
    return fn3(a,b)
}
function fn3(a,b){ // a+b
    a = a+b
    return a
}

callStackEx(2,3) // (2*3+3) + (3*2+2)

⭐ 싱글 스레드(single-threaded)

JavaScript는 기본적으로 싱글 스레드(single-threaded)이다.
싱글 스레드(single-threaded)한 번에 하나의 작업만 처리할 수 있음을 의미 한다.

⭐ JS가 과연 싱글 스레드(single-threaded)라고 할 수 있는가?

자바스크립트의 메인 스레드인 이벤트 루프가 싱글 스레드이기 때문에 싱글 스레드라고 부른다.
하지만 이벤트 루프만 독립적으로 실행되지는 않고 웹 브라우저나 NodeJS같은 멀티 스레드 환경에서 실행된다.

즉, 자바스크립트 자체는 싱글스레드 이지만 자바스크립트 런타임은 싱글 스레드가 아니다.

📌 자바스크립트 런타임의 비동기(Asynchronous)

  • 타이머 API (예: setTimeout, setInterval): 특정 시간 후에 코드를 실행.
  • 네트워크 요청 (예: fetch, XMLHttpRequest): 서버와의 데이터 전송을 처리.
  • DOM 이벤트 (예: addEventListener): 사용자 상호작용에 대한 응답을 처리.

✔ 멀티 스레드(Web API) 예제

setTimeout(function timeout() {
    console.log("Click the button!");
}, 2000);

setTimeout(function timeout() {
    console.log("Click the button!");
}, 2000);

console.log("Welcome to loupe.");

⭐ Promise

JavaScriptPromise비동기 작업의 결과를 처리하기 위한 객체이다.
Promise는 비동기 작업이 완료되었을 때 그 결과를 처리할 수 있는 방법을 제공하고, Promise는 주로 비동기 작업이 성공했는지 실패했는지를 처리하는 데 사용된다.

✔ Promise의 기본 구조

Promise는 다음 세 가지 상태를 가질 수 있다:

  • Pending (대기 중): 초기 상태. 비동기 작업이 아직 진행중.
  • Fulfilled (이행됨): 비동기 작업이 성공적으로 완료. 이 상태에서는 resolve 콜백이 호출.
  • Rejected (거부됨): 비동기 작업이 실패했습니다. 이 상태에서는 reject 콜백이 호출.

✔ Promise의 생성

Promisenew Promise() 생성자를 사용하여 생성한다.
생성자 함수에는 두 개의 매개변수 resolvereject가 있다.
이 함수들은 비동기 작업이 완료되었을 때 호출된다.

const promiseEx = (url) => {
	return new Promise((resolve, reject)=>{
      const delay = Math.floor(Math.random() * 5500) + 500;
      setTimeout(() => {
      	if(delay>=2000){
          resolve(console.log("resolve"))
        }else{
          reject(console.log("reject"))
        }
      }, delay)
    })  
}

promiseEx("")
promiseEx("")
promiseEx("")

✔ then과 catch 메서드

Promise 객체thencatch 메서드를 사용하여 비동기 작업의 결과를 처리한다.

then(onFulfilled, onRejected): Promise가 이행된 경우 호출된다. 이 메서드는 두 개의 콜백 함수를 인수로 받는다. 첫 번째는 작업이 성공적으로 완료되었을 때 호출되고, 두 번째는 실패했을 때 호출된다.

catch(onRejected): Promise가 거부된 경우 호출된다. 이 메서드는 작업이 실패했을 때만 호출된다.

const promiseEx = (url) => {
	return new Promise((resolve, reject)=>{
      const delay = Math.floor(Math.random() * 5500) + 500;
      setTimeout(() => {
      	if(delay>=2000){
          resolve("resolve")
        }else{
          reject("reject")
        }
      }, delay)
    })
}


const ex1 = promiseEx("");
ex1.then(result => {
    console.log(result); // "then resolve"
  })
  .catch(error => {
    console.log(error); // "catch reject" (실패 시)
  });

✔ async/await

async/awaitpromise의 코드의 가독성이 떨어지고 에러가 어디서 일어났는지 보기 어려워진다는 단점을 보완해준다.

📌async 함수

async 함수는 자동으로 Promise를 반환하도록 해준다.
함수 앞에 async를 붙이면 해당 함수는 자동으로 비동기 함수가 된다.

async function handleSubmit() {
	...
	return exampleAsync
	// return Promise.resolve(exampleAsync) // 위와 같은 결과
}

📌await 함수

await는 async 함수 내에서만 사용될 수 있는 표현식으로, Promise의 결과를 기다리는 데 사용된다.
await는 해당 Promise의 상태가 바뀔 때까지 코드가 기다린다. Promise가 성공 상태 또는 실패 상태로 바뀌기 전까지는 다음 연산을 시작하지 않는 것이다.

사실상 awaitthen()과 같은 역할을 하는데, 콜백 함수를 등록할 필요가 없기 때문에 더 편리하다

// 비동기 작업을 모사하는 함수
function fetchData() {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve("Data fetched successfully");
    }, 1000); // 1초 후에 데이터 반환
  });
}

// async 함수 정의
async function getData() {
  console.log("Fetching data...");
  
  // 비동기 함수에서 await 사용
  let data = await fetchData();
  
  console.log(data); // "Data fetched successfully"
}

// async 함수 호출
getData();
profile
반려묘 하루 velog

0개의 댓글