티스토리 뷰

동기처리

현재 실행중인 코드가 종료되기 전까지 다음 줄의 코드를 실행하지 않는 것이다.
위에서부터 순서대로 차례대로 진행한다.

ex) if문, 반복문(for, while), 함수호출

 

비동기처리

현재 실행중인 코드가 종료되기 전에 다음줄의 코드를 동시에 실행하는 것이다.

ex) callback(), Promise(), 비동기 API, Web API

 

function getName(cb) {
    setTimeout(() => {
        cb("Elice");
    }, 2000);
}

function getAge(cb) {
    setTimeout(() => {
        cb(20);
    }, 2000);
}

function getAddress(cb) {
    setTimeout(() => {
        cb("abcd@gmail.com");
    }, 2000);
}

위출력 결과를 console.log를 한번만 사용해야 한다면 어케 해야할까??

 

아래는 callback()함수를 사용한 예제이다. 

콜백이란 다른 함수의 인자로 전달되는 함수이다.(주로 비동기 프로그래밍에서 자주 사용된다.)

콜백지옥 : 콜백 함수 내에 계속 콜백 함수가 중첩된 경우 => 가독성 떨어짐, 에러처리 힘듦, 유지보수 어려움 

getName((name) => {
    getAge((age) => {
        getAddress((address) => {
            console.log(name, age, addr)
        })
    })
})

콜백함수 안에 콜백함수를 반복해서 호출해야 name, age, eAddr을 한꺼번에 접근할 수 있다.

비동기 함수가 3개 쓰이고, 각 2초씩 걸리므로 6초 뒤에 Elice 20 abcd@gmail.com 이 출력된다.

 

Promise

위와 같은 콜백지옥을 Promise를 사용해 탈출할 수 있다.

 

Promise의 장점

  1. 비동기 처리 시점을 명확하게 표현할 수 있다.
  2. 연속된 비동기 처리 작업을 수정, 삭제, 추가하기 편하고 유연하다.
  3. 비동기 작업 상태를 쉽게 확인할 수 있다.
  4. 코드의 유지 보수성이 증가한다.
function getName() {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve("Elice");
        }, 2000);
    })
}

function getAge() {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve(6);
        }, 2000);
    })
}

function getAddress() {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve("Seoul");
        }, 2000);
    })
}

Promise
    .all([getName(), getAge(), getAddress()])
    .then((res) => {
        const [name, age, address] = res;
        console.log(name, age, address)
    })

Promise.all()은 병렬적으로 배열의 원소에 있는 프로미스를 동시에 실행시킨다.

따라서 2초후에 Elice 6 Seoul을 출력할 수 있다. 하지만, 한개라도 실패(reject)하면 기다리지 않고 즉시 종료한다.

즉, 동시에 Promise객체를 반환하는 함수들을 실행할 수 있는 것이다.

(콜백함수는 불가능하다)

 

Promise의 3가지 상태

  • 대기(pending) : 이행하거나 거부되지 않은 초기 상태
    상태변경 조건 : 프로미스가 생성된 직후

  • 이행(fulfilled) : 연산이 성공적으로 완료됨
    상태변경 조건 : resolve 함수 호출

  • 거부(rejected) : 연산이 실패함
    상태변경 조건 : reject 함수 호출

그러므로, await을 쓰지 않을시, 현재 내 로직에서 return 된 Promise 객체는 아무것도 실행되지 않은 초기 상태의 Promise인 것이다.

 

await은 Promise객체를 실행하고 기다리지만, await을 쓰지 않으면 실행이 되진 않았기 때문에 결과 값에 pending 상태의 Promise배열만 남아있게 된 것이다.

 

프로미스의 후속 처리 메서드

후속 처리 메서드로는 .then, .catch, .finally 가 있다.

  • then : 프로미스의 비동기 처리 결과를 전달 받는다, 원래는 (성공처리콜백, 실패처리콜백) 두개를 인자로 받지만 보통 에러 처리는 catch 메서드 사용
  • catch : 실패(reject) 했을 때만 호출된다.
  • finally : 프로미스의 성공 여부에 상관없이 무조건 한 번 호출된다.

후속처리 메서드들을 연속적으로 호출하는 것을 프로미스 체이닝이라고 한다

let a = 10;

const test = new Promise((resolve, reject) => {
  if(a > 5) {
    resolve("True");
  } else {
    reject("False");
  }
});

test
  .then(res => console.log(res))
  .catch(err => console.log(err))
  .finally(() => console.log("finally"));   // 프로미스 체이닝
  
  //출력
  // True
  // finally

 

 

 

async() 함수 - await 키워드

Promise() 코드를 간결하게, 직관적이게 작성하는 문법

async () => {
    const name = await getName();
    const age = await getAge();
    const address = await getAddress();

    console.log(name, age, address);
}

await을 씀으로써 비동기함수안에서 동기함수처럼 동작을 하게된다. 즉, name이 실행되고 나서, age가 실행되고, 다음으로 address가 실행되는 것이다. await 키보드 때문에 6초 후Elice 6 Seoul이 출력된다.

await을 쓰지 않는다면, pending 상태의 Promise 객체가 return 된다. 

async / await 에서는 try catch문을 사용하여 에러처리가 가능하다.(promise의 resolve,reject라고 생각)

 

 

 

'개발공부 > 기술면접 대비' 카테고리의 다른 글

Ajax, Axios란??  (0) 2023.04.02
Restful API  (0) 2023.03.28
JWT 토큰??  (0) 2023.03.26
[JS] 깊은복사(deep copy), 얕은복사(shallow copy)  (0) 2023.03.23
[JS] 브라우저의 렌더링 과정  (0) 2023.03.23
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함