JS 확실히 알아가기 - 동기비동기

Seuling·2022년 6월 25일
0

FE

목록 보기
28/42
post-thumbnail

동기비동기관련해서 항상 헷갈렸다.
이번에 공부하며 제대로 면접에 도움이 될 수 있도록 준비해본다.

동기 비동기

자바스크립트 싱글 스레드 작업 수행방식

동기 처리 방식 문제점

멀티 쓰레드

그러나! 자바스크립트는 멀티 쓰레드가 불가능한 싱글쓰레드방식만 가능함!!

비동기 작업

비동기 예시

function taskA(a, b, cb) {
  setTimeout(() => {
    const res = a + b;
    cb(res);
  }, 3000); //3초 후 실행
}

function taskB(a, cb) {
  setTimeout(() => {
    const res2 = a * 2;
    cb(res2);
  }, 1000); //1초 후 실행
}

function taskC(a, cb) {
  setTimeout(() => {
    const res = a * -1;
    cb(res);
  }, 2000); //2초 후 실행
}

taskA(3, 4, (res) => {
  console.log("A TASK RESULT :", res);
});

taskB(7, (res) => {
  console.log("B TASK RESULT :", res);
});

taskC(14, (res) => {
  console.log("C TASK RESULT: ", res);
});

console.log("코드끝");

실행순서 : console.log("코드끝") ->taskB -> taskC -> taskA

JS Engine

Heap

변수나 상수 등의 메모리 저장하는 공간

Call Stack

동기방식으로 작동

작성한 코드의 실행에 따라 호출 스택에 쌓는 영역

two()종료
three()종료

비동기방식으로 작동




3초 후 콜백큐로 감!


콜백함수 실행 후 Main Context 종료

taskA(4, 5, (a_res) => {
  console.log("A RESULT:", a_res);
  taskB(a_res, (b_res) => {
    console.log("B RESULT:", b_res);
    taskC(b_res, (c_res) => {
      console.log("C RESULT :", c_res);
    });
  });
});


A의 결과값이 B에 들어가고, B의 결과값이 C에 들어가게되는!

비동기 작업이 가질수 있는 3가지 상태

promise 미사용


function isPositive(number, resolve, reject) {
  setTimeout(() => {
    if (typeof number === "number") {
      //성공 -> resolve
      resolve(number >= 0 ? "양수" : "음수");
    } else {
      //실패 -> reject
      reject("주어진 값이 숫자형 값이 아닙니다.")
    }
  }, 2000);
}

isPositive(10, (res)=>{
    console.log("성공적으로 수행됨:", res)
}, (err)=>{
    console.log("실패 하였음", err)
});

//성공적으로 수행됨: 양수
function isPositiveP(number) {
  const executor = (resolve, reject) => {
    //실행자
    setTimeout(() => {
      if (typeof number === "number") {
        //성공 -> resolve
        resolve(number >= 0 ? "양수" : "음수");
        console.log(number);
      } else {
        //실패 -> reject
        reject("주어진 값이 숫자형 값이 아닙니다.");
      }
    }, 2000);
  };
  const asyncTask = new Promise(executor); 
  //비동기 작업 자체인 프로미스를 저장할 asyncTask를 만들어주고 new키워드로 Promise를 생성해주고,
  //promise 객체의 생성자로 비동기작업의 실질적인 실행자함수executor를 넘겨주면 전달하는 순간 자동으로 실행됨
  return asyncTask;
}

const res = isPositiveP(101);

res.then((res)=>{
    console.log("작업성공:", res)
}).catch((err)=>{
    console.log("작업실패")
})

Promise 사용 (콜백함수처럼)

// function taskA(a, b, cb) {
//   const executorA = (resolve, reject) => {
//     setTimeout(() => {
//       const res = a + b;
//       cb(res);
//     }, 3000);
//   };
//   return new Promise(executorA);
// }

function taskA(a, b) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const res = a + b;
      resolve(res);
    }, 3000);
  });
}

function taskB(a) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const res = a * 2;
      resolve(res);
    }, 1000);
  });
}
function taskC(a) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const res = a * -1;
      resolve(res);
    }, 2000);
  });
}

Promise(then 체이닝)

taskA(5, 1)
  .then((a_res) => {
    console.log("A RESULT:", a_res);
    return taskB(a_res);
  })
  .then((b_res) => {
    console.log("B RESULT :", b_res);
    return taskC(b_res);
  })
  .then((c_res) => {
    console.log("C RESULTL", c_res);
  });

이렇게 나눠서도 사용가능함

const bPromiseResult = taskA(5, 1).then((a_res) => {
  console.log("A RESULT:", a_res);
  return taskB(a_res);
});

console.log("중간 나눔 구분선");
console.log("중간 나눔 구분선");
console.log("중간 나눔 구분선");

bPromiseResult
  .then((b_res) => {
    console.log("B RESULT :", b_res);
    return taskC(b_res);
  })
  .then((c_res) => {
    console.log("C RESULTL", c_res);
  });

async & await

//async

async function helloAsync() {
  return "hello Async";
}
// async : 함수가 Promise를 반환하도록 만드는 능력이있음!! 


console.log(helloAsync());

helloAsync().then((res) => {
  console.log(res); 
});

//결과값
//Promise { 'hello Async' }
//hello Async

async 사용

function delay(ms) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
}

//async

async function helloAsync() {
  return delay(3000).then(() => {
    return "hello Async";
  });
}
// async : 함수가 Promise를 반환하도록 만드는 능력이있음!!

console.log(helloAsync());

helloAsync().then((res) => {
  console.log(res);
});

원하는것은 3초 후 helloAsync()실행되는것인데, 코드가 너무 길다! await 사용

await 사용

async function helloAsync() {
  await delay(3000);
  return "hello Async";
}

await키워드가 붙은 함수의 호출은 동기적으로 작동을 함 뒤에있는 함수가 끝나기 전까지 그 아래에 있는 코드를 실행하지 않음!

function delay(ms) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
}

async function helloAsync() {
  await delay(3000);
  return "hello Async";
}

async function main() {
  const res = await helloAsync();
  console.log(res);
}

main();

API (Application Programming Interface)

응용 프로그래밍 인터페이스

응용 프로그램에서 사용할 수 있또록, 운영체제나 프로그래밍 언어가 제공하는 기능을 제어할 수 있게 만든 인터페이스를 뜻한다. 주로 파일 제어, 창 제어, 화상 처리, 문자 제어 등을 위한 인터페이스를 제공한다.

문제는!!!!!!!!!!!!????????!!!!!!!!!!!!
API호출의 응답을 언제받을지 모른다는것!

연습 (jsonplaceholder)

let response = fetch("https://jsonplaceholder.typicode.com/posts").then(
  (res) => {
    console.log(res);
  }
);

API의 객체 자체를 반환하기에 다른 값들 도 있음!

async function getData() {
  let rawResponse = await fetch("https://jsonplaceholder.typicode.com/posts");
  let jsonResponse = await rawResponse.json();
  console.log(jsonResponse);
}
getData()

profile
프론트엔드 개발자 항상 뭘 하고있는 슬링

0개의 댓글