동기/ 비동기

Taehee Kim·2022년 5월 23일
0

JavaScript

목록 보기
14/17
post-thumbnail

📌 동기(동시에 수행 X)

자바스크립트는 원래 기본적으로 동기적 처리를 한다. 즉 위에서 아래로 하나씩 순차적으로 실행을 하게 된다.

📌 비동기 (동시에 수행)

비동기 함수들은 바로 실행이 되지 않고 웹브라우저 API를 호출하여 일단 백테이지와 콜배큐에 추가하고 다른 함수들이 다 실행된 후에여 호출 스택에 넣어 실행한다.

비동기 처리를 하면 바로 실행이 되지 않기 때문에 화면이 순간 멈춰 보이기도 하고 처리하는 시간이 오래 걸린다. 하지만, 비동기처리로 코드 실행 순서를 조작할 필요가 있을 때 사용하게 된다.

  • 종류: promise, awit/async, fetch 등

💡 비동기 코드 실행 순서

  • setTimeout은 브라우저가 제공하는 비동기 함수, 시간이 지나면 콜백 함수를 불러옴—> 브라우저 API
  • 비동기 처리는 일단 브라우저에게 처리를 맡겨 놓는다.
  • 백그라운드 > 테스크 큐 > 호출 스택 > 콘솔
  • 지연시간이 다 되어도 호출 스택에 있는 다른 코드들이 먼저 다 실행되어야 비동기 코드 호출 스택으로 이동이 가능
  • 백그라운드 > 태스크큐로 가려면 호출 스택에 아무것도 남지 않아야 함
  • setTimeout 변별처리 가능 백그라운드에 따로 1초 기다리고 있으니까

📌 callback 함수

함수를 미리 만들어뒀다가 나중에 호출하여 사용하는 함수

(콜백 함수의 예시)

// 예시1
const 버튼 = document.querySelector('.button');
버튼.addEventListener('click',fucntion(){}); 

//예시2 
function 함수하나 (aa){
	console.log('hello');
	aa('world');
} 

함수하나(console.log);
// hello
// world (함수하나() 안에 콘솔로그 안 찍으면 error)

//예시2가 가능한 이유는 아래 코드처럼 표현이 원래 가능함
let taehee = console.log;
taehee('hello world'); // heelo world
function dessert(count, eat, good) {
		count < 3 ? eatDessert() : goodDessert();
}

function eatDessert() {
    console.log('오늘 먹어야 할 간식을 먹어주세요');
}

function goodDessert() {
    console.log('오늘 먹어야할 간식을 모두 먹었습니다');
}

dessert(4, eatDessert, goodDessert);

콜백지옥 발생 (길어지는 체이닝)

  • 가독성이 너무 안 좋음
  • 비즈니스 로직을 이해하기 어려워짐
  • 유지보수/ 디버깅 어려워짐
    - 탈출 방법 1) 기명함수로 정리 2) promise 사용하기
loadScript('1.js', function(error, script) {

  if (error) {
    handleError(error);
  } else {
    // ...
    loadScript('2.js', function(error, script) {
      if (error) {
        handleError(error);
      } else {
        // ...
        loadScript('3.js', function(error, script) {
          if (error) {
            handleError(error);
          } else {
            // 모든 스크립트가 로딩된 후, 실행 흐름이 이어집니다. (*)
          }
        });

      }
    })
  }
});

📌 promise

콜백함수를 비동기로 처리하는 방법

✔ 기본 문법

const promise = new Promise((resolve, reject) => {
	console.log("hello");//executor(제작코드,실행함수) 
});
  • executor은 new Promise에 전달되는 함수
  • new Promise 생성되면 executor는 자동 실행됨
  • resolve와 reject는 JS에서 자체 제공하는 콜백 함수, 둘 중 하는 꼭 호출해야 함.
  • reslove는 value, reject는 error와 호출

✔ promise에는 3가지 단계가 있다.
- pending: 대기 상태
- fulfilled: 이행 상태 (resolved)
- rejected: 실패 상태

(출처: 알잘딱깔센 JavaScript)

✔ resolve 땐 then, resolve된 값은 then 파라미터로 들어간다.

let p = new Promise(function(resolve, reject) {
    resolve('hello world');
}).then(메시지 => {
    alert(메시지); //hello world
    return 메시지.split(' ')[0] //hello
}).then(메시지 => {
    alert(메시지); //hello
    return 메시지[0] //h
}).then(메시지 => {
    alert(메시지); //h
});
//hello world
//hello
//h
//h

✔ reject면 catch로 바로 실행된다.

✔ resolve로 실행되다가 중간에 throw error를 만나면 중간을 뛰어넘고 catch로 실행
✔ finally는 성공/실패 상관없이 실행

📌 async/ await

1) promise 단점으로부터 탄생

  • 특정 조건에 따라 분기 나누기 어렵
  • 에러 파악 어려움
  • .then 지옥 가능성

2) ‘syntatic sugar’
3) promise의 resolved를 반환
4) await와 사용하기

  • await은 동기처리, promise가 실행될 때까지 기다린다
  • await은 promise 앞에서만 사용가능하고 async와 사용하여 동기처리를 한다.
  • promise.all을 쓰면 병렬처리
  • await으로 동기처리지만 Promise.all으로 비동기처리
  • 병렬처리를 하지 않는 것은 각자 동기처리임으로 총 시간이 총 6.5초!
  • 그런데 all로 병렬처리하여 사용하면 비동기적으로 처리할 수 있어 총 5초만 걸려서 세 개의 값이 동시에 나온 것.
// 동기처리 //

setTimeout(()=> {
    console.log('5초 끝!')
}, 5000);

setTimeout(()=> {
    console.log('10초 끝!')
}, 10000);

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

const myCake = async () => {
    await cook(3000);
    return '케이크';
};

const myCoffee = async () => {
    await cook(2000);
    return '커피';
};
const myCookie = async () => {
    await cook(5000);
    return '쿠키';
};

async function asyncProcess() {
    const cake = await myCake();
    console.log(cake);
    const coffee = await myCoffee();
    console.log(coffee);
    const cookie = await myCookie();
    console.log(cookie);
}

asyncProcess(); 
// 비동기처리 //

setTimeout(()=> {
    console.log('5초 끝!')
}, 5000);

setTimeout(()=> {
    console.log('10초 끝!')
}, 10000);

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

const myCake = async () => {
    await cook(3000);
    return '케이크';
};

const myCoffee = async () => {
    await cook(2000);
    return '커피';
};
const myCookie = async () => {
    await cook(5000);
    return '쿠키';
};

async function promiseProcess() {
   const results = await Promise.all([myCake(), myCoffee(), myCookie()]);
 console.log(results);
}

promiseProcess();

0개의 댓글