Javascript & Typescript/이해하기

[JS] Promise 이해하기 -2 (Promise 체이닝, Promise.all, async/await)

adjh54 2022. 3. 13. 19:14
728x170

 

해당 글은 이전 Promise에 대한 정의에 이어서 추가로 이해할 Promise Chaning, Promise.all 그리고 async/await 구문에 대해서 이해하기 위한 글입니다.

 

 

이전 Promise에 대한 정의가 궁금하면 아래에 이전 글을 참조하였습니다

 

 

[JS] Promise 이해하기 -1 (콜백함수, 정의, 요청상태)

해당 글은 Promise를 사용하기 이전에 callback 함수를 사용할 때와의 비교 및 Promise에 대한 이해 그리고 Promise의 요청 상태에 대해서 이해하기 위한 글입니다 1. Promise를 사용하기 이전 비동기 처리

adjh54.tistory.com

 

 

1) 프로미스 체이닝(Promise Chaning)


💡 비동기 함수의 처리 결과를 가지고 다른 비동기 함수를 호출하는 경우 함수의 호출이 중첩되어 복잡도가 높아진다. 이에 따라 프로미스는 후속 처리 메서드를 체이닝 하여 여러 개의 프로미스를 연결하여 사용할 수 있다.
[사용 예시] 프로미스 체이닝 예시
const _newPromise = () => {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve(1);
        }, 1000);
    });
};

const _chaningPromise = () => {
    _newPromise()
        .then((res) => {
            console.log('결과값1 :: ', res);	// 1
            return res + 10;
        })
        .then((res) => {
            console.log('결과값2 :: ', res); 	// 11
            return res + 10;
        })
        .then((res) => {
            console.log('결과값3 :: ', res);	// 21
        });
};

_chaningPromise()
  • _newPromise() 함수로 Promise를 정의한다.
  • _changingPromise()를 함수를 호출하여 _newPromise()가 최초 호출되고, 해당 값을 다음. then()으로 전달을 하고 연산을 한 뒤 return으로 연산 값을 다음으로 넘겨준다.

 

 

2) promise.all([])


💡 여러 개의 비동기 처리를 모두 일괄 병렬 처리를 하고자 할 때 사용한다. 인자로는 배열 형태를 받는데 이 배열에 있는 Promise가 모두 이행 상태(fulfilled) 일 때만 모든 처리결과를 배열에 저장하여 새로운 Promise배열에 저장하여 반환한다.
  • 하나의 Promise가 거절(rejected) 상태가 있다면, 해당 Promise.all()은 에러(. catch)로 반환이 된다.
[더 알아보기] 

병렬 처리?
- 하나의 진행 중인 프로세스가 종료될 때까지 기다리지 않고 동시에 처리하는 것을 의미한다.

 

 

[사용 예시] Promise.all 내에 값들이 모두 성공일 경우
useEffect(() => {
    (async () => {
        await newPromise()
            .then((res) => {
                console.log("Success Result :: ", res); // Success Result : [10, 20, 30]
            })
            .catch((error) => {
                console.log('error :: ', error);
            });
    })();
}, []);

const newPromise = () => {
    return Promise.all([
        new Promise((resolve) => setTimeout(() => resolve(10), 1000)),
        new Promise((resolve) => setTimeout(() => resolve(20), 2000)),
        new Promise((resolve) => setTimeout(() => resolve(30), 3000)),
    ]);
};

 

[사용 예시] Promise.all 내에 상태가 거부(rejected) 상태가 존재하는 경우
useEffect(() => {
    (async () => {
        await newPromise()
            .then((res) => {
                console.log("success Result :: ", res);
            })
            .catch((error) => {
                console.log('error :: ', error); // error :: 20
            });
    })();
}, []);

const newPromise = () => {
    return Promise.all([
        new Promise((resolve) => setTimeout(() => resolve(10), 1000)),
        new Promise((resolve, reject) => setTimeout(() => reject(20), 2000)),
        new Promise((resolve, reject) => setTimeout(() => reject(30), 3000)),
    ]);
};

 

[사용 예시] Promise.all에는 일반 값도 넘길 수 있다.
useEffect(() => {
    (async () => {
        await newPromise()
            .then((res) => {
                console.log("Success Result :: ", res); // Success Result : [10, 100, 1000]
            })
            .catch((error) => {
                console.log('error :: ', error);
            });
    })();
}, []);

const newPromise = () => {
    return Promise.all([
        new Promise((resolve) => setTimeout(() => resolve(10), 1000)),
        100,
        1000			
    ]);
};

 

3) async / await


1. async/await란 무엇인가?


💡 async/await

- 기존에 추가된 '콜백 함수'의 문제점을 해결하기 위해  ES8에서 추가된 문법으로 비동기적인 작업을 동기식으로 처리할 수 있게 해줍니다.
- async 함수를 사용하여 비동기적인 작업을 수행하고 await 키워드를 사용하여 작업이 완료될 때까지 기다립니다.
  • 등장 순서 : 콜백 함수(ES5 이전) → Promise(ES6) → async/await(ES8)
  • async/await 장점 : 상대적으로 코드가 간결하고 가독성이 높아서 로직을 파악하기 쉬우며 디버깅도 간단해졌음.

 

2. async


💡 async

- 함수 내에 ‘async’ 키워드를 적는 것은 Async function이라는 것을 정의하는 것이며, 암묵적으로 해당 함수는 Promise를 사용하여 결과를 반환한다.

 

[사용 예시] 해당 async 함수로 정의를 하면 Promise.then() / Promise.catch()로 반환을 해준다.
useEffect(() => {
    (async () => {
        _asyncTest().then((response) => {
            console.log(response);
        });
    })();
}, []);

const _asyncTest = async () => {
    return '안녕하세요 Async 함수 테스트 중입니다.';
};

 

[사용 예시] async 함수로 정의를 하지 않으면 아래와 같이 ‘에러'를 반환을 해준다.
useEffect(() => {
    (async () => {
        _asyncTest().then((response) => {
            console.log(response);
        });
    })();
}, []);

const _asyncTest = () => {
    return '안녕하세요 Async 함수 테스트 중입니다.';
};

 

 

3. await


💡 await

- Promise가 이행상태(fulfilled)이거나 거부 상태(rejected)가 되던지 끝날 때까지 기다리는 함수를 의미한다.
  • await : 함수 중에서 Promise로 반환하는것들에 대해서 await를 붙인다
[사용 예시] await를 이용한 예시 
const newPromise = () => {
	return Promise.resolve('안녕하세용');
};

const awaitTest = async () => {
	await newPromise();
};

 

오늘의 결론


Promise에 대해서 잘 이해해보았습니다.
이전 글까지 합쳐서 콜백함수 -> Promise -> await /async에  달하는 문법을 이해하였습니다. 
앞으로 비동기 통신을 사용할때 명확하게 사용합시다.

 

오늘도 감사합니다😀

 

그리드형