자바스크립트 중에 제일 중요한 개념이라고 할 수 있다.
Promise는 비동기 작업을 감싸는 객체이다.
- 비동기 작업실행 (ex. setTimeout)
- 비동기 작업 상태 관리
- 비동기 작업 결과 저장
- 비동기 작업 병렬 실행
- 비동기 작업 다시 실행
- etc
대기
-아직 작업이 완료되지 않은 상태
성공
-비동기작업이 성공적으로 마무리 된 상태
실패
-비동기작업이 실패한 상태
대기, 성공, 실패 이 3가지 상태를 관리한다.
성공상태로 바뀔 때 resolve, 실패상태로 바뀔때는 reject 로 나누어 준다.
예시)
유투브 영상 로딩중 → 대기
유투브 영상 로딩완료 → resolve → 성공
유투브 영상 로딩실패 → reject → 실패
const promise = new Promise((resolve,reject)=>{
// 비동기 작업실행하는 함수 입력.
setTimeout(() => {
console.log('안녕')
resolve();
},2000)
})
생성자를 이용해 promise 객체를 생성하고, 인수로는 비동기 작업을 진행할 콜백함수를 넣어준다. 이를 executor 함수 라고 부른다.
해당 콜백함수는 promise객체가 생성됨과 동시에 자동 실행된다.
위의 예시 코드를 실행해보면, 페이지가 로드되고 나서 2초 뒤에 자동으로 console이 찍히는 것을 확인할 수 있다.
promise 객체에는 두가지의 매개변수가 들어간다.
resolve, reject 이다. 첫번째 매개변수에는 비동기함수를 성공상태로 바꾸는 함수, 두번째 매개변수로는 실패 상태로 바꾸는 함수가 들어가있다. 따라서, 성공상태를 알리고 싶으면 resolve 함수를 호출해주면 된다.
—> 이게 무슨 말이냐면, promise 객체를 console에 찍어보면 해당 객체의 state, 즉 상태값 속성도 나오는데, 해당 상태값을 성공 혹은 실패로 바꾸어주는 함수이다.
만약 성공시 진행할 함수 그 뒤에 resolve 함수를 불러주면, 이 resolve()함수는 그 promise 객체의 state값을 성공으로 변환시켜준다.
❕ 콜백함수
콜백 함수는 다른 함수에 전달되어 특정 상황이나 이벤트가 발생했을 때 호출되는 함수입니다. 이 함수는 일반적으로 비동기적인 작업이 완료되었을 때 실행되거나, 어떤 조건이 충족되었을 때 호출됩니다. 즉, 콜백 함수는 다른 함수의 매개변수로 전달되어 나중에 호출되는 함수입니다. 이때 콜백 함수는 보통 해당 이벤트나 작업의 결과를 처리하거나 다음 단계의 작업을 실행하는 데 사용됩니다.
prototype , promiseState , promiseResult
prototype : promise
promiseState : “fullfilled” → 이건 resolve() 호출시 생성
promiseResult : undefined → 이 값을 받으려면, resolve() 함수 내부에 인수를 넣어주어야 한다. reject() 도 마찬가지다. 두 함수 다 인수로 넣은 값을 promise의 결과값으로 반환한다. setTimeout 함수 내부에서 resolve나 reject 둘 중에 뭐가 호출 되냐에 따라서 해당 promise의 state,그리고 result 값이 달라지게 된다.
const promise = new Promise((resolve,reject)=>{ // 매개변수 규칙
//비동기 작업 실행하는 함수. 자동 실행됨.
// executor
setTimeout(() => {
//const num = "10";
if(typeof num === 'number'){
resolve(num + 10);
}else{
reject("숫자가 아닙니다")
}
}, 2000);
})
return promise;
}
promise.then((value)⇒{
console.log(value)
})
위 처럼 변수에 저장한 promise 객체 뒤에 .then (그 후에) 이걸 붙히면, 해당 promise 객체가 실행하는 executor 함수의 반환값을 자동으로 매개변수로 받아서 사용할 수 있는 함수를 작성할 수 있다.
❕ 주의사항
promise의 executor 함수가 resolve 값을 반환할 때만 실행된다.
즉 성공했을 때만 실행된다.
실패했을 경우 실행할 함수는 .then이 아니라 .catch() 메서드를 사용해야 한다.promise.then((value)=>{ //console.log(value) // 성공 }).catch((error)=>{ //console.log(error) //실패 })같은 promise 객체를 다시 반환하기 때문에, 이렇게 then과 catch를 연달아서 붙혀 사용이 가능하다. → promise chaining
// 예시
function add10 (num){
const promise = new Promise((resolve,reject)=>{ // 매개변수 규칙
//비동기 작업 실행하는 함수. 자동 실행됨.
// executor
setTimeout(() => {
//const num = "10";
if(typeof num === 'number'){
resolve(num + 10);
}else{
reject("숫자가 아닙니다")
}
}, 2000);
})
return promise;
}
const p = add10(0) // return된 promise 객체는 해당함수를 호출한 곳으로 자동 반환된다.
함수를 호출하며 인수를 넘겨주고, 그 호출한 함수를 변수로 만들어주면, 해당 함수가 실행된 반환값(promise객체)이 그 변수에 자동으로 저장된다!
promise를 더 직관적으로 사용할 수 있게 도와주는 메서드.
async와 await 키워드를 사용하는 함수는 자동으로 Promise를 반환한다.
동기함수 → 비동기함수로 전환할 수 있다.
어떤 함수를 비동기 함수로 만들어주는 키워드
함수가 프로미스를 반환하도록 변환해주는 키워드
async function getData(){
return {
name : “dfdfd”,
id:”dffdf”
}
}
위처럼 함수 앞에 async를 붙히면, 객체를 반환하는게 아니라, 이 객체를 결과값으로 갖는 promise 객체를 반환하는 함수로 변하게 된다. 그러나 만약에,
async function getData(){
return new Promise((resolve,rejected)=>{
setTimeout(() => {
resolve({
name: "amy",
id : "lee"
})
}, 1500);
})
}
위처럼 애초에 promise 객체를 반환하는 비동기 함수였다면, async는 별다른 기능을 하지 않는다. async는 await과 함께 사용해야한다.
async 함수 내부에서만 사용이 가능한 키워드
await는 async 함수 내에서 비동기적으로 실행되는 코드를 동기적으로 처리할 수 있게 해준다.
function async printData(){
// getData().then((result)=>{
// console.log(result)
// });
const data = await getData();
console.log(data)
}
위 코드의 주석처럼 기존에는 promise 객체를 받아올 때 promise객체 뒤에 .then을 붙혀서 인수로 promise객체의 결과값을 받아와서 사용했었다. 그러나 await을 사용하면 이럴 필요가 없다.
일단 promise의 결과값을 받아오는 printData() 함수의 앞에 async을 붙혀주고, getData() 함수 호출시 앞에 await을 붙혀주면, 알아서 결과값이 들어올 때까지 기다린다. 즉 promise가 완료된 ‘그 후에’ 알아서 실행된다.
try, catch
promise 생성자를 사용해 promise를 반환하면 resolve와 reject를 .then().catch()로 작성했었다. async, await는 resolve와 reject를 try와 catch를 사용하여 구분한다.