동기, 비동기에 대하여..

김예린·2024년 1월 12일
0

동기(synchronize): 작업이 순차적으로 실행됨. 한 작업이 끝나야만 다음 작업이 시작된다. 요청이 오면 응답을 받아야만 다음 요청이 실행됨.

비동기(asynchronize): 작업이 동시에 실행될 수 있다. 한 작업이 끝나는 것을 기다리지 않고 다음 작업을 진행할 수 있다.
자원의 낭비가 적다.

'비동기 함수의 동기적 표현'이라는 것은

function fetchData() {
  return new Promise(resolve => {
    setTimeout(() => {
      console.log('Data fetched!');
      resolve();
    }, 1000);
  });
}

async function main() {
  console.log('Start');

  // await를 사용하여 fetchData 함수가 완료될 때까지 기다림
  await fetchData();

  console.log('End');
}

main();

위 코드에서 fetchData() 함수는 1초 후에 비동기적으로 데이터를 가져오는 작업을 수행한다. 그러나 main() 함수에서 await fetchData() 부분에서 fetchData()가 완료될 때까지 기다린다. 이로인해 코드의 실행 흐름이 마치 동기적으로 실행되는 것처럼 보이는 것을 말한다.

Promise는 비동기작업을 다루기 위한 객체이다.
비동기 연산의 최종 완료 또는 그 결과 값을 나타낸다.

// Promise 생성
let promise = new Promise(function(resolve, reject) {
  // 비동기 작업을 수행하는 코드

  if (/* 작업 성공 */) {
    resolve(value); // 작업이 성공적으로 끝나면 resolve 호출
  } else {
    reject(error); // 에러가 발생하면 reject 호출
  }
});

// Promise 사용
promise.then(
  function(value) { /* 성공시 실행할 함수 */ },
  function(error) { /* 실패시 실행할 함수 */ }
);
  1. promise 생성:
    new promise로 promise객체를 생성한다.
    Promise 생성자 함수는 인자로 resolve와 reject라는 콜백함수를 받는다.
    비동기 작업이 완료되면 성공시: resolve호출하고 결과 값 반환
    실패 시: reject 호출하여 에러 반환
  2. Promise 사용:
    then 메소드를 사용하여 성공 및 실패 시에 각각 실행할 함수를 등록할 수 있다

fetch 함수가 이미 프로미스를 반환하는 이유는 자바스크립트에서 비동기 작업을 처리하기 위해 사용되는 표준 API 중 하나 이기 때문.
fetch함수는 네트워크를 통해 데이터를 가져오는 비동기 작업을 수행하는데 사용되며, 이 함수는 Promise를 반환하여 비동기적으로 작동합니다.
fetch는 데이터를 가져오는 작업을 수행하는 함수이다 => 데이터를 가져오는건 오래걸린다!
그니까 비동기처리를 해야한다: 데이터 가져오는 작업을 기다리지 않고 다음을 실행해야한다! 시간없다!
이런 작업을 다루기 위해 Promise라는 객체가 사용되는거다 왜냐면 데이터 가져오는 작업이 다끝났는지 실패했는지를 알려줘야하기 때문이다!
1. fetch함수는 즉시 결과를 반환하지 않고, 대신에 데이터가 수신될 때까지 기다리지 않고 다음 코드 실행
2. Promise 반환(성공,실패)
fetch함수는 비동기 작업의 결과를 알려주기 위해 promise 반환 promise 객체는 세가지 상태 가짐: Pending(대기중), Fulfilled(이행됨),Rejected(거부됨)
3.Promise의 이행 또는 거부
네트워크 요청이 성공하면 promise는 이행 상태로 전환되며 그 결과로 Response 객체를 가진다.
네트워크 요청이 실패하면 promise는 거부 상태로 전환되며 에러 정보를 가진다.

Promise.all
여러 개의 프로미스를 병렬로 실행하고 모든 프로미스가 성공적으로 완료되었을때만 성공하며 하나라도 실패하면 해당시점에서 실패한다.

Promise.all([
  fetch('https://jsonplaceholder.typicode.com/posts/1').then(response => response.json()),
  fetch('https://jsonplaceholder.typicode.com/posts/2').then(response => response.json()),
  fetch('https://jsonplaceholder.typicode.com/posts/3').then(response => response.json())
]).then(posts => {
  console.log(posts); // 3개의 게시물 데이터가 배열로 반환됩니다.
}).catch(error => {
  console.error('Error:', error);
});

세개의 다른 네트워크 요청을 병렬로 한번에 실행한다. 모든 프로미스가 완료될 때까지 기다리고 모두 성공하면 then실행이되고 실패하면 catch 블록이 실행된다.

Promise.allSettled
이 메서드는 여러 프로미스를 병렬로 실행하고, 모든 프로미스가 완료되었을 때(성공,실패여부 상관없이) 그 결과를 배열로 반환한다. 이 메서드는 각각의 프로미스가 성공했는지 실패했는지에 관계없이 모든 프로미스가 완료될 때까지 기다린다.
반환 값은 각 프로미스의 결과에 대한 정보를 담은 객체들의 배열이다.

let promises = [
  fetch('https://api.example.com/item1'),
  fetch('https://api.example.com/item2'),
  fetch('https://api.example.com/item3')
];

Promise.allSettled(promises)
  .then((results) => {
    results.forEach((result, index) => {
      if (result.status === 'fulfilled') {
        console.log(`#${index + 1} 성공:`, result.value);
      }
      if (result.status === 'rejected') {
        console.log(`#${index + 1} 실패:`, result.reason);
      }
    });
  });

Promise.allSettled(promises): Promise.allSettled 메서드는 여러 개의 프로미스를 받아 병렬로 실행합니다.
results.forEach((result, index) => {...}): 결과 배열을 순회하면서 각각의 프로미스에 대한 정보를 처리합니다.
result.status: 프로미스의 상태를 나타내며, 'fulfilled' 또는 'rejected'일 수 있습니다.
result.value: 프로미스가 성공한 경우의 값이며, 실패한 경우에는 undefined입니다.
result.reason: 프로미스가 실패한 경우의 이유(에러)를 나타냅니다.
Promise.allSettled를 사용하면 여러 프로미스의 실행 결과를 성공과 실패에 상관없이 모두 확인할 수 있습니다.

profile
아자아자

0개의 댓글