JavaScript
promise
1
2
3
const pr = new Promise((resolve, reject) => {
// 실행코드
});
- 우리가 어떤 것을 주문했을 때, 그것이 완료되기까지 시간이 걸리고 완료 후 주문자에게 완료되는 것을 전달하는 것을
promise
라고 부른다. - 성공했을 때와 실패했을 때가 나뉘며, 어떤 일이 완료됐을 때 실행되는 콜백함수를 넘겨준다.
1
2
3
4
5
6
7
8
9
10
11
new Promise();
state: pending(대기);
result: undefined;
// resolve(value) 성공 시
state: fulfilled(이행됨);
result: value;
// reject(error) 실패 시
state: rejected(거부됨);
result: error;
- 실행 후 반환되는 결과를 주문한 사람에게 넘겨주듯이 똑같이
then
을 사용하여 처리할 수 있다. - 첫 번째 인자로는 성공했을 때 실행되는 함수를, 두 번째 인자로는 실패했을 때 실행되는 함수를 넣어준다.
- 성공하거나 실패했을 때에 또 다른 함수는 실행되지 않는다.
- 가독성을 위해 실패했을 때를 명확히 구분지어
catch
문을 사용하여 에러 발생 시를 구분 짓는 것이 좋다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const pr = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("OK");
}, 3000);
});
pr.then(
function (result) {
console.log(result + "가지러 가자");
},
function (err) {
console.log("다시 주문해주세요");
}
);
// catch
pr.then(function(result){console.log(result + "가지러 가자");})
.catch(function(err))
finally
는 실행 및 실패 후 항상 실행된다.
callback hell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const f1 = function () {
setTimeout(function () {
console.log("1번 주문 완료");
}, 1000);
};
const f2 = function () {
setTimeout(function () {
console.log("2번 주문 완료");
}, 1000);
};
const f3 = function () {
setTimeout(function () {
console.log("3번 주문 완료");
}, 1000);
};
console.log("시작");
f1(function () {
f2(function () {
f3(function () {
console.log("끝");
});
});
});
promise
없이 위 코드를 실행 시, 계속 콜백함수를 불러와야 하며, 이 코드가 깊어지며callback hell
을 만든다.- 이를
promise
로 처리한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
const f1 = () => {
return new Promise((res, rej) => {
setTimeout(() => {
res("1번 주문 완료");
}, 1000);
});
};
const f2 = (message) => {
console.log(message);
return new Promise((res, rej) => {
setTimeout(() => {
res("2번 주문 완료");
}, 1000);
});
};
const f3 = (message) => {
console.log(message);
return new Promise((res, rej) => {
setTimeout(() => {
res("3번 주문 완료");
}, 1000);
});
};
console.log("시작");
f1()
.then((res) => f2(res))
.then((res) => f3(res))
.then((res) => console.log(res))
.catch(console.log)
.finally(() => {
console.log("끝");
});
- 위처럼
promise
가 연결되어 있는 것을 프로미스 체이닝(Promise chaining)이라고 한다.
Promise.all
- 여러 개의
promise
를 함께 처리한다. - 배열을 받고
then
으로 처리할 수 있으며, 한꺼번에 시작한다. - 하나의 정보라도 누락되면 모든 것이 누락되기 때문에 주의해야 한다.
f1
을reject
로 실행하면f2,f3
가 모두 실행되지 않는다.
- 모든 정보가 누락되지 않아야 할 때도 유용하게 사용된다.
1
Promise.all([f1(), f2(), f3()]).then((res) => console.log(res));
Promise.race
all
은 모든 작업이 완료되어야 하지만,race
는 하나라도 완료되면 실행된다.- 사용 방법은
all
과 같다. - 이미지를 로딩할 때와 같이 하나라도 완료되면 로딩되도록 사용할 때 사용된다.
async await
Promise.then
을 사용하여 코드가 끝나고 나서야 실행하였던 것과 같다.- 함수에 사용되며
async
가 사용된 함수에await
를 사용하여 코드가 끝날 때까지 기다릴 수 있다. Promise
가 반복되는 상황에서 가독성이 높은 코드를 작성할 수 있으며 에러 발생에 대해서는try...catch
문으로 작성한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
const f1 = (message) => {
return new Promise((res, rej) => {
setTimeout(() => {
res(res + "주문완료");
}, 2000);
});
};
const f2 = (message) => {
return new Promise((res, rej) => {
setTimeout(() => {
rej(new Error("err..."));
}, 2000);
});
};
f1().then((res) => res + "하였습니다.");
// 위 코드와 동일하지만 가독성이 좋다.
async function order() {
const result = await f1();
return result;
}
// reject 처리 try...catch
// try를 시도하고 에러가 발생하면 catch문을 실행한다.
async function order2() {
try {
const result = await f2();
return result;
} catch (e) {
return e;
}
}