프로미스란 비동기 처리 상태와 결과를 관리하는 객체이다
프로미스는 주로 서버에서 받아온 데이터를 화면에 표시할 때 사용한다
프로미스는 비동기 처리를 위한 전통적인 콜백 패턴이 가진 단점을 보완하기 위하여 도입되었으며
비동기 처리 시점을 명확하게 표현할 수 있고
콜백 패턴에서 처리하기 어려웠던 에러를 처리할 수 있다는 장점이 있다
프로미스를 사용하면 비동기 메서드에서 마치 동기 메서드처럼 값을 반환할 수 있다
다만 최종 결과를 반환하는 것이 아니라,
미래의 어떤 시점에 결과를 제공하겠다는 약속(promise)를 반환한다
//2024.07.02
const promise = new Promise((resolve, reject) => {
//promise는 resolve와 reject메서드를 매개변수로 가진다.
setTimeout(() => {
const num = "tes";
if (typeof num === "number") {
//resolve메서드는 promiseState를 fulfilled로 변경
//resolve메서드의 인자가 promise값으로 반환됨
resolve(num + 10);
} else {
//reject메서드는 promiseState를 rejected로 변경
//reject메서드의 인자가 에러 메세지로 반환됨
reject("type 에러");
}
}, 2000);
return promise;
});
//promise가 성공했을 때 실행
//then은 resolve의 인자를 매개변수로 가진다.
promise.then((value) => {
console.log(value);
});
//promise가 실패했을 때 실행
//catch는 reject의 인자를 매개변수로 가진다.
promise.catch((error) => {
console.log(error);
});
//promise는 promise를 반환하기 때문에 체이닝이 가능하다.
promise
.then((value) => {
console.log(value);
})
.catch((error) => {
console.log(error);
});
프로미스는 3가지의 상태를 가진다
pending(대기)
fulfilled(비동기 처리 이행)
rejected(비동기 처리 실패)
fulfilled와 rejected상태를 묶어 settled상태라고 한다.
프로미스는 pending상태에서 settled상태가 될 수 있으나
반대로는 변할 수 없다.
프로미스의 비동기 상태가 변화하면 이에 따른 후속 처리를 해야 한다
이를 위해 프로미스는 후속 메서드 then, catch, finally를 제공한다
then
catch
finally
세 개의 프로미스 후속 처리 메서드는 언제나 프로미스를 반환한다
then메서드는 두 개의 콜백 함수를 인수로 전달받는다
첫 번째 콜백 함수는 프로미스가
fulfilled상태(resolve함수가 호출된 상태)가 되면 호출된다
이 때, 콜백 함수는 프로미스의 비동기 처리 결과를 인수로 전달받는다
두 번쨰 콜백 함수는 프로미스가
rejected상태(reject함수가 호출된 상태)가 되면 호출된다
이 때, 콜백 함수는 프로미스의 에러를 인수로 전달받는다
catch 메서드는 한 개의 콜백 함수를 인수로 전달받는다
catch의 콜백 함수는 프로미스가 rejected상태인 경우만 호출된다
catch메서는 then(undefined, onRejected)와 동일하게 동작한다
finally 메서드는 한 개의 콜백 함수를 인수로 전달받는다
finally 메서드의 콜백 함수는 프로미스의 성공, 실패와 상관없이 무조건 한 번 호출된다
프로미스 후속 처리 메서드는 언제나 프로미스를 반환하므로
연속적으로 체이닝하여 호출할 수 있다
체이닝을 한 경우 콜백들이 직렬로 처리되므로
모든 콜백 함수의 소요시간+a의 시간이 소요되게 된다
promise는 5가지 정적 메서드를 제공한다
비동기 콜백, 이벤트 핸들러가 test queue에 저장되는 것과 달리
프로미스의 후속 처리 메서드는 microtesk queue에 저장된다
mq는 tq보다 처리 우선 순위가 높으므로
비동기 콜백, 이밴트 핸들러보다 우선적으로 실행된다
promise기반의 web API이다
//async
//어떤 함수를 비동기 함수로 만들어주는 키워드
//함수가 프로미스를 반환하도록 변환해주는 키워드
//단 함수 내에서 return으로 프로미스를 반환하는 경우, async는 동작하지 않고 return값을 반환한다.
async function getData() {
return {
name: "김정현",
id: "JH",
};
}
//await
//async 함수 내부에서만 사용이 가능 한 키워드
//비동기 함수가 다 처리되기를 기다리는 역할
async function printDate() {
const date = await getData();
console.log(date);
}
printDate();
콜백 형식
const fs = require("fs");
fs.readFile("./readme.txt", (err, data) => {
if (err) {
throw err;
}
console.log("1번", data.toString());
fs.readFile("./readme.txt", (err, data) => {
if (err) {
throw err;
}
console.log("2번", data.toString());
fs.readFile("./readme.txt", (err, data) => {
if (err) {
throw err;
}
console.log("3번", data.toString());
});
});
});
---
promise 형식
const fs = require("fs").promises;
fs.readFile("./readme.txt")
.then((data) => {
console.log("1번", data.toString());
return fs.readFile("./readme.txt");
})
.then((data) => {
console.log("2번", data.toString());
return fs.readFile("./readme.txt");
})
.then((data) => {
console.log("3번", data.toString());
return fs.readFile("./readme.txt");
})
.catch((err) => {
console.error(err);
});
---
async/await 형식
const fs = require("fs").promises;
async function main() {
let data = await fs.readFile("./readme.txt");
console.log("1번", data.toString());
data = await fs.readFile("./readme.txt");
console.log("2번", data.toString());
data = await fs.readFile("./readme.txt");
console.log("3번", data.toString());
}
main();
//top level await이 추가되면서 async함수로 감싸지 않아도 await이 동작하게 되었다.