
Promise
- 비동기 작업을 제어하기 위해 나온 개념으로 callback hell에서 어느정도 벗어날 수 있게 함
- Promise로 정의된 작업끼리는 연결할 수 있고, 코드의 depth가 크게 증가하지 않게해준다
1) Promise 만들기
const promise = new Promise((resolve, reject) => {
// promise 내부에서 비동기 상황 종료될 때, resolve 함수 호출
// promise 내부에서 오류 상황일 때, reject 함수 호출
})
Promise에서는 then을 이용해 비동기 작업 이후 실행할 작업을 지정함
function asyncPromiseWork() {
//code...
return new Promise((resolve, reject) => {
//code...
return resolve('complete')
})
}
//then의 result에는 resolve를 호출하며 넘긴 complete가 들어있음
asyncPromiseWork().then(result => console.log(result))
Promise의 then 내에서 promise를 return할 경우 이어진다.
기존의 콜백함수를 promise 형태로 만들 수 있음
promiseWork()
.then(result => {
return promiseNextWork(result)
}).then(result => {
return promiseThirdWork(result)
}).then(result => {
return promiseFinalWork(result)
})
Promise chain 중 reject가 발생했을 경우 catch문으로 잡을 수 있다. (catch문을 안넣으면 chain이 멈춘다)
promiseWork()
.then(result => {
return promiseNextWork(result)
}).then(result => {
return promiseThirdWork(result)
}).then(result => {
return promiseFinalWork(result)
}).catch(e => {
alert('에러가 발생했군요.')
})
finally에서는 성공/실패 여부 상관없이 무조건 실행
promiseWork()
.then(result => {
return promiseNextWork(result)
}).then(result => {
return promiseThirdWork(result)
}).then(result => {
return promiseFinalWork(result)
}).catch(e => {
alert('에러가 발생했군요.')
}).finally(() => {
alert('작업이 끝났습니다.')
})
기존의 callback 함수를 promise 형태로 만들 수 있다.
resolve를 작업이 끝나는 순간에 호출하면 된다.
const delay = (delayTime) => new Promise((resolve)
setTimeout(resolve, delayTime)
})
delay(5000)
.then(() => {
doSomething()
retrun delay(3000)
).then(() => {
console.log('complete!)
})

ex) 기존 request 함수 promise 형태로 바꾸기
export function request (url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.addEventListener("load", (e) => {
if(xhr.readyState === 4) {
if(xhr.status === 200) {
resolve(JSON.parse(xhr.responseText))
} else {
reject(xhr.statusText)
}
}
})
xhr.addEventListenr('error', (e) => reject(xhr.statusText))
xhr.open('GET', url);
xhr.send()
})
}
2) 내장 함수
① Promise.all() : 배열 안 모든 promise를 처리 후 then / 여러 promise를 동시에 처리할 때 유용
const promise1 = delay(1000)
const promise2 = delay(2000)
const promise3 = delay(3000)
Promise.all([promise1, promise2, promise3]).then(() => {
})
② Promise.race() : 여러 promise중 하나라도 resolve/reject 되면 종료
Promise.race(iterable)

③ Promise.any(iterable) : 여러 Promise 중 하나라도 resolve 되면 종료 / reject는 무시하고, resolve 되는 것만 처리
Promise.any(iterable)

⑤ Promise.allSettled(iterable) : 여러 Promise들이 성공했거나, 실패했거나 상관없이 모두 이행된 경우 처리

⑥ Promise.resolve : 주어진 값으로 이행하는 Promise.then 객체를 만듦, 주어진 값이 Promise인 경우 Promise가 반환
항상 Promise를 반환해야할 때 유용하다.
⑦ Promise.reject : 주어진 값으로 reject 처리된 이행하는 Promise.then 객체를 만듦, 주어진 값이 Promise인 경우 Promise가 반환
async, await
- Promise를 이용해도 코드 작성에 불편함이 있어 해결하기 위해 등장
- 동기식 코드처럼 보이는 장점이 있다. (실행은 비동기)
ex) then 중첩 문을 async, await 문으로 작성하기
const delay = (delayTime) => {
return new Promise(resolve => setTimeout(resolve, delayTime));
}
const work = () => {
console.log('work run')
delay(1000)
.then(() => {
console.log('work 1 done');
return delay(1000)
})
.then(() => {
console.log('work 2 done');
return delay(1000)
})
.then(() => {
console.log('work 3 done');
return delay(1000)
})
.then(() => {
console.log('work 4 done');
return delay(1000)
})
}
work();
const work = async () => {
console.log('work run')
await delay(1000)
console.log('work 1 done');
await delay(1000)
console.log('work 2 done');
await delay(1000)
console.log('work 3 done');
await delay(1000)
console.log('work 4 done');
}
코드가 깔끔해지는 것을 볼 수 있다.
선언 방식 2가지
async function asyncFunction () {
const res = await request(...)
}
const asyncFunction = async () {
const res = await request(...)
}
- async 키워드 함수가 붙은 함수는 실행결과를 Promise로 감싼다
- 기본적으로 await는 async로 감싸진 함수 scope에서만 사용 가능했지만, top level await가 등장하여 top level에서도 사용 가능하다.

fetch
fetch api
- 비동기 http 요청을 좀 더 편하게 해주는 API
- XMLHTTPRequest을 대체
- Promise 기반으로 동작
fetch api 사용하기
- fetch의 기본 응답 결과는 Response 객체
- Response 객체를 얻은 뒤엔 응답을 json이나 text로 바꾸는 처리를 해야한다.
- json, text 외에도 다양한 method들이 있다. (blob - 이미지처리)
<html>
<head>
<title>kdt 4</title>
</head>
<body>
<script>
fetch('https://kdt-frontend.programmers.co.kr/todos')
.then(res => {
return res.json()
})
.then(data => {
console.log(data)
})
</script>
</body>
</html>
- fetch는 HTTP error가 발생하더라도 reject 되지 않는다.
- 네트워크 에러나 요청이 완료되지 못한 경우에만 reject 된다.
- => 서버 요청 중 에러가 생겼을 경우에도 then은 떨어지므로, response의 status code나 ok를 체크해주는 것이 좋다.
- fetch의 두번째 인자로 옵션을 줄 수 있다.
'데브코스 프론트엔드 5기 > VanillaJS를 통한 자바스크립트 기본 역량 강화 1' 카테고리의 다른 글
| 231012[Day18] VanillaJS를 통한 자바스크립트 기본 역량 강화 1 (7) (0) | 2023.10.13 |
|---|---|
| 231011[Day17] VanillaJS를 통한 자바스크립트 기본 역량 강화 1 (6) (0) | 2023.10.12 |
| 231009 [Day15] VanillaJS를 통한 자바스크립트 기본 역량 강화 1 (4) (0) | 2023.10.10 |
| 231006 [Day14] VanillaJS를 통한 자바스크립트 기본 역량 강화 1 (3) (0) | 2023.10.09 |
| 231005[Day13] VanillaJS를 통한 자바스크립트 기본 역량 강화 1 (2) (0) | 2023.10.06 |