Promise란?
자바스크립트를 사용하다 보면 빠른 속도, 가독성을 위해 비동기적 작업을 사용할 때가 많다.
Promise는 자바스크립트에서 비동기적 작업을 편하게 관리하도록 도와주는 객체이다.
비동기적 작업은 특정 작업이 끝나지 않아도 다음 작업을 시작하는 작업이다.
반대로 동기적 작업은 특정 작업이 끝날때까지 다음 작업을 시작하지 않고 대기하다가 기존 작업이 끝나고 다음 작업을 시작하는 작업이다.
Promise 만들기
아래 예제는 callback 함수를 사용하는 비동기적 코드 예시이다. 이런 코드가 많아지면 가독성이 많이 떨어진다.
function double(number, callback) {
setTimeout(() => {
if (!callback) return;
const result = number * 2;
console.log(`${number} * 2 = ${result}`);
callback(number * 2);
}, 500);
}
double(1, result => {
double(result, result => {
double(result, result => {
double(result, result => {
console.log(`최종 결과는 ${result}입니다.`);
})
})
})
})
// 출력 력과
// 1 * 2 = 2
// 2 * 2 = 4
// 4 * 2 = 8
// 8 * 2 = 16
// 최종 결과는 16입니다.
그럼 Promise를 만들어 코드를 개선해보겠다.
Promise에 인자값 resolve는 작업이 성공했을때, reject는 작업이 실패했을때 사용하는 함수다.
resolve 또는 reject 함수를 호출할 때는 결괏값 또는 오류를 인자로 넣을 수 있다.
function double(number) {
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
if (typeof number !== 'number') {
reject(new Error('Parameter is not a vaild'));
return;
}
const result = number * 2;
console.log(`${number} * 2 = ${result}`);
resolve(result);
}, 500);
});
return promise;
}
double(1).then(
result => {
console.log('resolved', result);
}
)
// 출력 결과
// 1 * 2 = 2
// resolved 2
double(numm).then(
result => {
// Promise가 거부되기 때문에 이 코드는 실행되지 않음
console.log('resolved', result);
}
).catch(
e => {
console.error(e);
}
)
// 출력 결과
// Error: Parameter is not a vaild
double(1)
.then(result => double(result))
.then(result => double(result))
.then(double) // 파라미터가 하나뿐인 경우는 다음과 같이 선언 가능
.then(result => {
console.log(`최종 결과: ${result}`);
})
// 출력 결과
// 1 * 2 = 2
// 2 * 2 = 4
// 4 * 2 = 8
// 8 * 2 = 16
// 최종 결과: 16
async와 await
async와 await라는 키워드는 Promise를 더욱 쉽게 사용할 수 있게 해준다.
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function process() {
console.log('안녕하세요.');
await sleep(1000); // 1초 sleep
console.log('반갑습니다.');
}
// 출력 결과
// 안녕하세요.
// 반갑습니다.
"안녕하세요."라는 텍스트다 출력되고 다음 1초 뒤에 "반갑습니다."라는 텍스트가 출력된다.
이 문법을 사용하려면 함수를 선언할 때 앞부분에 async 키워드를 붙히고, Promise의 앞부분에 await를 사용하면 then 또는 catch 없이도 쉽게 비동기 작업을 관리할 수 있다.
그럼 위에 작성한 double 예제 코드로 async와 await를 사용해보겠다.
function double(number) {
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
if (typeof number !== 'number') {
reject(new Error('Parameter is not a vaild'));
return;
}
const result = number * 2;
console.log(`${number} * 2 = ${result}`);
resolve(result);
}, 500);
});
return promise;
}
async function process() {
let result = 1;
result = await double(result);
result = await double(result);
result = await double(result);
result = await double(result);
return result;
}
process().then(
result => {
console.log(`최종 결과: ${result}`);
}
)
// 출력 결과
// 1 * 2 = 2
// 2 * 2 = 4
// 4 * 2 = 8
// 8 * 2 = 16
// 최종 결과: 16
함수를 선언할 때 function 키워드 앞에 async를 붙혀주면 해당 함수를 호출했을 때 함수 내부에서 반환한 값을 이행하는 Promise를 반환한다. process()에서 반환하는 값이 Promise이기 때문에 여기서 또 then을 사용할 수 있다.
만약 함수가 function 키워드로 선언한 함수가 아니라 화살표 함수 문법을 통해 선언된 함수라면 다음과 같은 형태로 사용하면 된다.
const fn = async () => {
...
}
async와 await를 사용할 때 오류에 대해 예외 처리하려면 try/catch 구문을 사용해야 한다.
async function process() {
try {
await double(null);
} catch (e) {
console.error(e);
}
}
process();
// 출력 결과
// Error: Parameter is not a vaild
'React Native' 카테고리의 다른 글
useEffect로 컴포넌트 변경 시 이벤트 실행 (0) | 2022.02.08 |
---|---|
AsyncStorage로 앱이 꺼져도 데이터 유지하기 (1) | 2022.02.07 |
React Native에서 알림창(Alert) 사용하기 (0) | 2022.02.07 |
백터 아이콘(Vector Icons) 사용하기 (0) | 2022.02.06 |
FlatList로 리스트 만들기 및 스크롤 감지 (0) | 2022.02.06 |