개발 공부/JavaScript 공부

[JavaScript] Promise.all

종범2 2020. 11. 22. 00:04

Promise

이전에 promise에 관한 내용을 설명한 적이 있었다.

jongbeom-dev.tistory.com/121?category=863255

 

[JavaScript] 프로미스(Promise)

비동기 함수를 사용할 때 성공한 경우와 실패한 경우에 따라 코드를 작성해야 하는 경우가 많다. 이때 가독성이 매우 떨어지는 코드를 작성하게 된다. 예를 들어 다음과 같은 testLuck이라는 이름

jongbeom-dev.tistory.com

정리하자면 콜백 함수가 promise를 리턴하도록 정의하면, 리턴 받은 promise의 .then 메서드와 .catch 메서드를 이용하여 가독성 높게 코드를 작성할 수 있다. 같은 예제를 이용하여 promise를 리턴하는 비동기 함수를 정의하였다.

var testLuck = (name) => {
    return new Promise((res,rej) => {
        setTimeout(() => {
            const ranInt = Date.now();
            if(ranInt%2 === 1){
                rej(name);
            }
            res(name);
        },1000)
    });
}

testLuck('kim')
	.then((name)=>console.log(name+' is Lucky'))
	.catch((name)=>console.log(name+' is Unlucky'));

testLuck 함수는 promise를 리턴한다. 이 promise를 실행하면 1초 뒤에 50%의 확률로 res나 rej 함수를 실행한다.

Promise.all이 필요한 상황

콜백 함수를 여러번 호출해야 하고, 그 결과값이 모두 모여야 하는 경우가 있다. 위의 예제를 이용한다면 여러 사람의 운을 테스트하는 경우라고 할 수 있겠다. 만약 테스트가 다 끝나고 결과를 출력해야 한다면 어떻게 코드를 짜야할까?

var userList = ['kim', 'lee', 'jung'];
var resultList = [];
userList.forEach(ele=>{
    testLuck(ele)
        .then((name)=>resultList.push({
                name,
                result: true
            }
        ))
        .catch((name)=>resultList.push({
                name,
                result: false
            }
        ));
})
console.log(resultList); // []

우선 Promise.all 없이 작성해보려고 노력했지만 실패했다. 아마 다들 이런식으로 많이 접근해보겠지만 이 경우는 resultList을 출력하면 빈 배열만 출력된다. testLuck은 비동기 함수이기 때문이다. 즉 Promise.all 없이 이 문제를 해결하려면 코드 작성이 까다로워진다.

Promise.all

Promise의 all 메서드는 promise로 구성된 배열을 인자로 받아 새로운 promise를 리턴한다. 리턴된 새로운 promise는 실행할 때 배열의 모든 promise를 실행하여 그 결과가 모두 나올 때까지 기다린 후 배열로 리턴한다. 즉 .then 메서드를 호출하면 promise를 모두 실행하고 그 결과를 배열로 만들어서 .then 메서드의 콜백 함수의 인자로 결과를 전달한다. 만약 하나라도 실패한다면 먼저 실패한 promise의 결과를 .catch 메서드의 콜백 함수의 인자로 결과를 전달한다. 작성한 코드는 다음과 같다.

var userList = ['kim', 'lee', 'jung'];
var promiseList = [];
userList.forEach(ele=>promiseList.push(testLuck(ele)));
Promise.all(promiseList)
    .then((res)=>{
    console.log(res +' is lucky');
    })
    .catch((res)=>{
    console.log(res + ' is unluck');
    });
// promise가 모두 성공한 경우 : kim,lee,jung is lucky
// kim의 promise가 실패한 경우 : kim is unluck

참고자료

developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

 

Promise.all()

Promise.all() 메서드는 순회 가능한 객체에 주어진 모든 프로미스가 이행한 후, 혹은 프로미스가 주어지지 않았을 때 이행하는 Promise를 반환합니다. 주어진 프로미스 중 하나가 거부하는 경우, 첫

developer.mozilla.org