// fakeRequestPromise('yelp.com/api/coffee/page1')
// .then(() => {
// console.log("IT WORKED!!!!!! (page1)")
// fakeRequestPromise('yelp.com/api/coffee/page2')
// .then(() => {
// console.log("IT WORKED!!!!!! (page2)")
// fakeRequestPromise('yelp.com/api/coffee/page3')
// .then(() => {
// console.log("IT WORKED!!!!!! (page3)")
// })
// .catch(() => {
// console.log("OH NO, ERROR!!! (page3)")
// })
// })
// .catch(() => {
// console.log("OH NO, ERROR!!! (page2)")
// })
// })
// .catch(() => {
// console.log("OH NO, ERROR!!! (page1)")
// })
// THE CLEANEST OPTION WITH THEN/CATCH
// RETURN A PROMISE FROM .THEN() CALLBACK SO WE CAN CHAIN!
fakeRequestPromise('yelp.com/api/coffee/page1')
.then((data) => {
console.log("IT WORKED!!!!!! (page1)")
console.log(data)
return fakeRequestPromise('yelp.com/api/coffee/page2')
})
.then((data) => {
console.log("IT WORKED!!!!!! (page2)")
console.log(data)
return fakeRequestPromise('yelp.com/api/coffee/page3')
})
.then((data) => {
console.log("IT WORKED!!!!!! (page3)")
console.log(data)
})
.catch((err) => {
console.log("OH NO, A REQUEST FAILED!!!")
console.log(err)
})
이렇게 위의 코드를 Promise 객체를 이용해서 엄청나게 간결하게 들여쓰기를 위 코드처럼 하지않고 가독성이 좋게 적어 낼 수 있다. 어디선가 막히면 catch
를 통해서 오류를 나타내 줄 수 있다.
const fakeRequest = (url) => {
return new Promise((resolve, reject) => {
const rand = Math.random();
setTimeout(() => {
if (rand < 0.7) {
resolve('YOUR FAKE DATA HERE');
}
reject('Request Error!');
}, 1000)
})
}
fakeRequest('/dogs/1')
.then((data) => {
console.log("DONE WITH REQUEST!")
console.log('data is:', data)
})
.catch((err) => {
console.log("OH NO!", err)
})
resolve와 reject될때 출력이 어떻게 될 지 잘 나온다 !
다른 예시를 보자면
// const delayedColorChange = (newColor, delay, doNext) => {
// setTimeout(() => {
// document.body.style.backgroundColor = newColor;
// doNext && doNext();
// }, delay)
// }
// delayedColorChange('red', 1000, () => {
// delayedColorChange('orange', 1000, () => {
// delayedColorChange('yellow', 1000, () => {
// delayedColorChange('green', 1000, () => {
// delayedColorChange('blue', 1000, () => {
// delayedColorChange('indigo', 1000, () => {
// delayedColorChange('violet', 1000, () => {
// })
// })
// })
// })
// })
// })
// });
//Promise를 사용해서 이 코드를 정리한다면,
const delayedColorChange = (color, delay) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
document.body.style.backgroundColor = color;
resolve();
}, delay)
})
}
delayedColorChange('red', 1000)
.then(() => delayedColorChange('orange', 1000))
.then(() => delayedColorChange('yellow', 1000))
.then(() => delayedColorChange('green', 1000))
.then(() => delayedColorChange('blue', 1000))
.then(() => delayedColorChange('indigo', 1000))
.then(() => delayedColorChange('violet', 1000))
.then
을 써주지 않으면, 코드는 위에서 아래로 작동하기 때문에 결국 보라색만 남게 된다. 그때 .then
을 사용해주면 차례대로 색이 변하는걸 볼 수 있다.
이 Promise에는 전부다 성공이어서 성공과 실패의 갈림길도 없다.
Async
깔끔하게 만들어준다 👀 함수를 비동기 함수로 선언하는 함수이다. 함수 앞에 async를 입력하여 비동기로 만들면 함수는 자동적으로 promise를 반환한다.
const sing = async () => {
throw "OH NO, PROBLEM!"
return 'LA LA LA LA'
}
sing()
.then(data => {
console.log("PROMISE RESOLVED WITH:", data)
})
.catch(err => {
console.log("OH NO, PROMISE REJECTED!")
console.log(err)
})
함수가 값을 반환할 때 resolve 상태로 반환이 될 것이다. 여기서 반환 값이 'LA LA LA LA'이다. 이게 어떤식으로 유용하냐면, 아래 코드처럼 sing().then(()=>{})
라고 적어줄때 비동기적으로 작동하게 된다. 프라미스가 정상적으로 이행되면 promise는 프라미스 객체의 result에 저장된 값을 반환하고, 반면 프라미스가 거부되면 마치 throw
문을 작성한 것처럼 에러가 던져집니다.throw "OH NO, PROBLEM!"
로 비동기 함수에 던져진 에러를 잡아주면 promise는 rejected된다.
const login = async (username, password) => {
if (!username || !password) throw 'Missing Credentials'
if (password === 'corgifeetarecute') return 'WELCOME!'
throw 'Invalid Password'
}
login('todd', 'corgifeetarecute')
.then(msg => {
console.log("LOGGED IN!")
console.log(msg)
})
.catch(err => {
console.log("ERROR!")
console.log(err)
})
Await
이 키워드는 비동기 코드를 쓰면서 동기적으로 보이게 해준다😯 기다리게 하는 역할인데, Promise값을 반환 할 때까지 기다리기 위해 비동기 함수의 실행을 일시 정지 시킨다. 비동기 함수에서만 적용돠기 때문에 async와 짝궁이다 !
const delayedColorChange = (color, delay) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
document.body.style.backgroundColor = color;
resolve();
}, delay)
})
}
// delayedColorChange('red', 1000)
// .then(() => delayedColorChange('orange', 1000))
// .then(() => delayedColorChange('yellow', 1000))
// .then(() => delayedColorChange('green', 1000))
// .then(() => delayedColorChange('blue', 1000))
// .then(() => delayedColorChange('indigo', 1000))
// .then(() => delayedColorChange('violet', 1000))
async function rainbow() {
await delayedColorChange('red', 1000)
await delayedColorChange('orange', 1000)
await delayedColorChange('yellow', 1000)
await delayedColorChange('green', 1000)
await delayedColorChange('blue', 1000)
await delayedColorChange('indigo', 1000)
await delayedColorChange('violet', 1000)
return "ALL DONE!"
// rainbow().then(() => console.log("END OF RAINBOW!"))
async function printRainbow() {
await rainbow();
console.log("END OF RAINBOW!")
}
printRainbow();
}
앞에서 색을 바꿔주는 코드를 봤는데, 이렇게 적어 줄 수 있다.
그리고 비동기 함수에서 실패를 하면 어떻게 처리를 했을까?
const fakeRequest = (url) => {
return new Promise((resolve, reject) => {
const delay = Math.floor(Math.random() * (4500)) + 500;
setTimeout(() => {
if (delay > 2000) {
reject('Connection Timeout :(')
} else {
resolve(`Here is your fake data from ${url}`)
}
}, delay)
})
}
async function makeTwoRequests() {
try {
let data1 = await fakeRequest('/page1');
console.log(data1);
let data2 = await fakeRequest('/page2');
console.log(data2);
} catch (e) {
console.log("CAUGHT AN ERROR!")
console.log("error is:", e)
}
}