JS 비동기 1편 - Promise
Promise
promise는 비동기에서 사용되는 연산으로,
리턴하는 프로미스 객체는
- 대기(pending): 이행하지도, 거부하지도 않은 초기 상태.
- 이행(fulfilled): 연산이 성공적으로 완료됨.
- 거부(rejected): 연산이 실패함.
세 가지 형태 중 하나로 나타난다.
resolve, reject
const promise = new Promise((resolve, reject) => {
if (true) {
resolve("Worked");
} else {
reject("Error");
}
});
프로미스에 성공 시 수행할 연산을 암묵적으로 resolve라 하고
실패 시 수행할 연산을 암묵적으로 reject라 한다.
promise는 성공을 하면(resolve가 실행되면)
fulfilled 상태를 리턴한다.
반대로 실패를 하면(reject가 실행되면)
rejected 상태를 리턴한다.
then
promise.then((result) => console.log(result));
then은 리턴된 프로미스 객체에 작업을 이어서 하게끔 해준다.
리턴된 fulfilled 상태의 프로미스 객체의 'Worked'는 result에 담기며
이를 콘솔에 출력한다.
promise
.then((result) => result + "!!")
.then((result2) => {
console.log(result2);
})
then은 하나 이상을 추가할 수 있다.
리턴한 데이터에 !!가 붙어서 출력된다.
catch
promise
.then((result) => result + "!!")
.then((result2) => {
throw Error;
console.log(result2);
})
.catch(() => console.log("Error"));
catch는 try catch문처럼 에러가 났을 경우 then대신 실행된다.
강제로 에러를 발생시켜서 catch를 실행시켜 본다.
promise
.then((result) => result + "1")
.then((result2) => result2 + "3")
.catch(() => console.log("error"))
.then((result3) => {
throw Error;
console.log(result3 + "2");
});
catch문은 보통 맨 마지막에 작성되는데
이유는 위처럼 catch문 이후 에러가 발생한다면 잡아낼 수 없기 때문이다.
catch문이 에러를 잡아내지 못하고 있다.
all
const promise2 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, "is");
});
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 1000, "Good");
});
const promise4 = new Promise((resolve, reject) => {
setTimeout(resolve, 3000, "isnt it?");
});
Promise.all([promise, promise2, promise3, promise4]).then((values) => {
console.log(values);
});
새로운 프로미스를 세 개 생성한 후 setTimeout을 적용해
각각 다른 시간에 실행되게끔 한다.
all을 사용하면 여러 개의 프로미스를 한 번에 실행시킬 수 있다.
여기서 all은 제일 결과가 늦게 나오는 promise를 기다려서
모두 실행이 끝나면 결과를 출력한다.
따라서 위 코드는 3초가 넘어서 출력을 한다.
fetch
const urls = [
"https://jsonplaceholder.typicode.com/users",
"https://jsonplaceholder.typicode.com/posts",
"https://jsonplaceholder.typicode.com/albums",
];
fetch(urls[0]); //return Promise
promise는 보통 api통신에 쓰인다.
fetch는 url주소를 통해 데이터를 가져오며 프로미스 객체를 리턴한다.
const urls = [
"https://jsonplaceholder.typicode.com/users",
"https://jsonplaceholder.typicode.com/posts",
"https://jsonplaceholder.typicode.com/albums",
];
Promise.all(
urls.map((url) => {
return fetch(url).then((res) => res.json());
})
)
.then((results) => {
console.log(results[0]);
console.log(results[1]);
console.log(results[2]);
})
.catch((err) => console.log(err));
각 3개의 url을 all로 fetch를 하면 세 개의 결과는 콘솔에 한 번에 출력된다.