[TIL] 비동기

krkorklo·2022년 8월 28일
0

TIL

목록 보기
14/29
post-thumbnail

비동기

  • 호출부에서 실행 결과를 기다리지 않고 실행 → Non-blocking
  • 싱글 스레드 환경에서 광범위하게 사용
  • 동기 처리와는 달리 순차적 처리가 보장되지 않는다

callback

  • 예상치 못한 순서로 코드가 실행되는 문제를 콜백으로 해결
function findUserAndCallBack(call) {
  setTimeout(function () {
    console.log("waited 0.1 sec.");
    const user = "krkorklo";
    call(user);
  }, 100);
}

findUserAndCallBack(function (user) {
  console.log("user:", user);
});

Promise

  • 콜백 함수로 비동기 처리를 하는 경우 콜백 지옥 발생 가능
function findUserAndCallBack() {
  return new Promise(function (resolve) {
    setTimeout(function () {
      console.log("waited 0.1 sec.");
      const user = "krkorklo";
      resolve(user);
    }, 100);
  });
}

findUserAndCallBack().then(function (user) {
  console.log("user:", user);
});

Promise 객체에 then() 메서드를 호출하여 결과값을 가지고 로직을 실행

Promise 객체

  • new 키워드와 생성자로 생성 가능
  • resolve : 미래 시점에 얻게 될 결과를 넘겨줌
  • reject : 미래 시점에 발생할 예외를 넘겨줌
new Promise((resolve, reject) => { ... } );

fetch

  • REST API를 호출할 때 사용되는 Promise 기반의 브라우저 내장 함수
  • then() : 결과값을 가지고 수행할 로직을 담은 콜백 함수를 인자로 받음
  • catch() : 예외 처리 로직을 담은 콜백 함수를 인자로 받음
fetch(url)
  .then((response) => console.log("response:", response))
  .catch((error) => console.log("error:", error));

method chaining

  • then()catch() 메서드는 또다른 Promise 객체를 리턴
    then()catch()를 연쇄적으로 호출 가능
fetch(url)
  .then((response) => response.json())
  .then((post) => post.userId)
  .then((userId) => url + userId)
  .then((url) => fetch(url))
  .then((response) => response.json())
  .then((user) => console.log("user:", user))
  .catch((error) => console.log("error:", error));

async/await

  • 기존의 비동기 처리 방식인 콜백 함수와 프로미스의 단점을 보완
async function userId() {
  const user = await fetch(url);
  console.log(user);
}
  • async : 비동기 작업을 하는 함수를 선언할 때 사용하며 async 함수의 리턴 값은 무조건 Promise
  • await : Promisefulfilled되거나 reject될 때까지 기다린다는 의미로 async 함수에서만 사용 가능
  • async 함수 바깥의 최상위 레벨 코드에선 await를 사용할 수 없어 then/catch를 사용

병렬처리

async function asyncHello(number) {
  return new Promise(resolve => setTimeout(() => {
    console.log('hello ' + number);
    resolve();
  }, 200))
}

async function main() {
  console.time();
  for (var i = 0; i < 10; i++) {
    await asyncHello(i);
  }
  console.timeEnd();
}

main();

위 코드는 0.2초 간격으로 실행되며 실행이 끝나기까지 2초가 넘게 걸림
→ 함수 실행 횟수가 많아질수록 전체 실행 시간이 더 많아진다
→ 비동기를 병렬로 처리해야 한다!

순차 실행

병렬 실행

async function asyncHello(number) {
  return new Promise(resolve => setTimeout(() => {
    console.log('hello ' + number);
    resolve();
  }, 200))
}

async function main() {
  console.time();

  const promises = [];
  for (var i = 0; i < 10; i++) {
    promises.push(asyncHello(i));
  }
  await Promise.all(promises);

  console.timeEnd();
}

main();

Promise.all은 Promise 배열을 매개변수로 받은 후 병렬로 처리
→ 모든 Promise가 이행되거나 처음으로 거부되는 때에 종료


https://wlswoo.tistory.com/36
https://seungtaek-overflow.tistory.com/4
https://www.daleseo.com/js-async-callback/
https://joshua1988.github.io/web-development/javascript/js-async-await/
https://elvanov.com/2597
https://inpa.tistory.com/entry/JS-📚-비동기처리-async-await

0개의 댓글