자바스크립트 복습 - 8

Stulta Amiko·2022년 5월 16일
0

자바스크립트 복습

목록 보기
8/12
post-thumbnail

프로미스

Promise는 비동기 작업의 최종 완료 또는 실패를 나타내는 객체입니다. 대부분 여러분은 이미 만들어진 promise를 사용했었기 때문에 이 가이드에서는 어떻게 promise를 만드는지 설명하기에 앞서 promise의 사용법에 대해 설명합니다.
기본적으로 promise는 함수에 콜백을 전달하는 대신에, 콜백을 첨부하는 방식의 객체입니다.

MDN에서 프로미스를 사용하는 방법에 대해서는 이런식으로 설명하고있다.

  • 콜백은 자바스크립트 Event Loop가 현재 실행중인 콜 스택을 완료하기 이전에는 절대 호출되지 않습니다.

  • 비동기 작업이 성공하거나 실패한 뒤에 then() 을 이용하여 추가한 콜백의 경우에도 위와 같습니다.

  • then()을 여러번 사용하여 여러개의 콜백을 추가 할 수 있습니다. 그리고 각각의 콜백은 주어진 순서대로 하나 하나 실행되게 됩니다.

그리고 프로미스는 위와같은 특징을 보장한다.

간단한 코드로 프로미스의 사용에 대해 보자

const promise1 = new Promise((resolve, reject) => {
    resolve("Success"); //Success
});

promise1.then(
    data => {
        console.log(data);
    }
)

resolve 함수에 파라미터로 들어간 값이 출력되는것을 알 수 있다.
setTimeout()을 사용하면 resolve가 호출되기 전 까지 일정 시간을 기다릴 수 있다.

const promise1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject(new Error("Error"));
    }, 2000);
});

promise1.then(
        data => {
            console.log(data);
        }
    )
    .catch(
        err => {
            console.error(err);
        }
    )

reject를 이용해서 오류를 처리하는 모습이다.
프로미스가 성공할때는 .then()을 사용하고
실패해서 오류를 처리할땐 .catch()를 이용한다.

프로미스 체이닝

프로미스에서 반환된것을 후속 프로미스의 기반으로 사용하여 프로미스를 계속해서 연결할 수 있다.

보통 두 개 이상의 비동기 작업을 순차적으로 실행해야 하는 상황을 흔히 보게 됩니다. 순차적으로 각각의 작업이 이전 단계 비동기 작업이 성공하고 나서 그 결과값을 이용하여 다음 비동기 작업을 실행해야 하는 경우를 의미합니다. 우리는 이런 상황에서 promise chain을 이용하여 해결하기도 합니다.

 const promise1 = new Promise((resolve, reject) => {
    resolve();
});

promise1.then(data => {
        return `working...`;
    })
    .then(data => {
        console.log(data); //working...
        throw "Failed";
    })
    .catch(err => {
        console.error(err); //failed
    });

프로미스가 성공하지않고 오류를 띄워도 연쇄적으로 연결해서 사용이 가능하다.
만약 위 코드에서는 두번째 .then()에서 오류를 띄웠지만
첫번째 .then()에서 오류를 띄우게 된다면 두번째 console.log는 실행되지 않고 바로 catch로 넘어가서 오류를 처리하게 된다.

Promise.resolve()/.reject()/.all()/.race()

Promise.resolve()/reject()

자동으로 성공하거나 실패할때 생성한다.
둘중 하나가 나오면 바로 성공/실패 처리하기때문에 바로 연결된다.

Promise.all()/race()

const promise1 = new Promise((resolve, reject) => {
    setTimeout(resolve, 500, 'first promise');
});

const promise2 = new Promise((resolve, reject) => {
    setTimeout(resolve, 1000, 'second promise');
});

promise1.then(data => {
    console.log(data);
})

promise2.then(data => {
    console.log(data);
})

위코드에선 promise 1이 0.5초만에 실행되고 1초가 되었을때 promise2가 실행되는 모습을 볼수 있다.

하지만 all()을 사용하게 된다면 모든 프로미스가 성공해야 하나의 프로미스를 반환한다.

const promise1 = new Promise((resolve, reject) => {
    setTimeout(resolve, 500, 'first promise');
});

const promise2 = new Promise((resolve, reject) => {
    setTimeout(resolve, 1000, 'second promise');
});

Promise.all([promise1, promise2])
    .then(data => {
        const [promise1data, promise2data] = data;
        console.log(promise1data, promise2data);
    });

위의 출력결과는 1초가 지난후에 first promise second promise 가 출력된다.

만약 둘다 성공한 경우가 아니라 하나가 실패하는 경우라면
실패한 오류가 출력되면서 전체를 실패처리한다.

race()는 말그대로 가장먼저 성공 혹은 실패하는 결과를 보여준다.

const promise1 = new Promise((resolve, reject) => {
    setTimeout(resolve, 500, 'first promise');
});

const promise2 = new Promise((resolve, reject) => {
    setTimeout(resolve, 1000, 'second promise');
});

Promise.race([promise1, promise2])
    .then(data => {
        console.log(data)
    });

위코드 같은경우는 promise 1이 500ms로 promise2 의 1000ms 보다 500ms나 빠르게 되니 first promise를 출력하고 종료된다.

0개의 댓글