04. Promise all, Promise.race

Promise 종류

const sleep = (ms) => {
    return new Promise(resolve => setTimeout(resolve, ms));
};

const getIanman = async () => {
    await sleep(2000);
    return '아이어 맨';
}

const getCamtin = async () => {
    await sleep(4000);
    return '캡틴아메리타'
}

const getAbanjuc = async () => {
    await sleep(5000);
    return '어벤저스'
}

const process = async () => {
    const Ianman = await getIanman();
    console.log(Ianman);
    const Camtin = await getCamtin();
    console.log(Camtin);
    const Abanjec = await getAbanjuc();
    console.log(Abanjec);
};

process();
// 결과)
아이어 맨
캡틴아메리타
어벤저스

현재 위 코드에서는 getIanman 는 2초, getCamtin 은 4초, getAbanjuc 은 5초가 걸리고 있습니다. 이 함수들을 process 함수에서 연달아서 사용하게 되면서, process 함수가 실행되는 총 시간은 11초가 됩니다.

지금은 getIanman -> getCamtin -> getAbanjuc 순서대로 실행이 되고 있는데요, 하나가 끝나야 다음 작업이 시작하고 있는데, 동시에 작업을 시작하고 싶다면, 다음과 같이 Promise.all 을 사용해야합니다.

Promise.all

동시에 작업을 시작하고 싶다면 Promise.all를 사용하자! Promise.all 등록한 프로미스 중 하나라도 실패하면, 모든게 실패 한 것으로 간주합니다.

const process = async () => {
    const start = Date.now();
    const results = await Promise.all([getIanman(), getCamtin(), getAbanjuc()])
    console.log(Date.now() - start);  // 시간이 얼마나 걸렸는지 확인하는 코드
    console.log(results);
};

process();
// 결과)
5001    // 시간이 얼마나 걸렸는지 확인하는 코드
[ '아이어 맨', '캡틴아메리타', '어벤저스' ]

만약에 여기서 배열 비구조화 할당 문법을 사용한다면 각 결과값을 따로 따로 추출해서 조회 할 수 있습니다.

const sleep = (ms) => {
    return new Promise(resolve => setTimeout(resolve, ms));
};

const getIanman = async () => {
    await sleep(2000);
    return '아이어 맨';
}

const getCamtin = async () => {
    await sleep(300);
    return '캡틴아메리타'
}

const getAbanjuc = async () => {
    await sleep(3000);
    return '어벤저스'
}

const process = async () => {
    const start = Date.now();
    const [ianman, camtin, abanjuc] = await Promise.all([getIanman(), getCamtin(), getAbanjuc()]);
    console.log(ianman+':', Date.now() - start);
    console.log(camtin+':', Date.now() - start);
    console.log(abanjuc+':', Date.now() - start);
};

process();
// 결과)
아이어 맨: 3006
캡틴아메리타: 3015
어벤저스: 3015

Promise.all 를 사용 할 때에는, 등록한 프로미스 중 하나라도 실패하면, 모든게 실패 한 것으로 간주합니다.

Promise.race

이 함수는 Promise.all 과 달리, 여러개의 프로미스를 등록해서 실행했을 때 가장 빨리 끝난것 하나만의 결과값을 가져옵니다.

const process = async () => {
    const start = Date.now();
    const first = await Promise.race([getIanman(), getCamtin(), getAbanjuc()])
    console.log(first+':', Date.now() - start);
};

process();
// 결과)
캡틴아메리타: 307

Promise.race 의 경우엔 가장 먼저 끝난 Promise 가 실패하면 이를 실패로 간주합니다. 따라서, 현재 위의 코드에서 getCamtin 에서 에러를 발생시킨다면 에러를 잡아낼 수 있지만, getIanman 이나 getAbanjuc 에서 발생한 에러는 무시됩니다.

ex)

Promise.all 로 에러를 잡아낼 때 try/catch 문 사용해보자

const process = async () => {
    try {
        const start = Date.now();
        const [ianman, camtin, abanjuc] = await Promise.all([getIanman(), getCamtin(), getAbanjuc()])
        console.log(ianman+':', Date.now() - start);
        console.log(camtin+':', Date.now() - start);
        console.log(abanjuc+':', Date.now() - start);
    } catch(e) {
        console.log('process Error:', e);
    }
};

Last updated