1. Promise
01. Promise-1
- ES6 부터 JS의 표준 내장 객체로 추가되었다.
- ES6를 지원하는 브라우저나 Node.js에서 전역에 있는 Promise를 확인할 수 있다.
생성자를 통해서 프로미스 객체를 만들 수 있고, 생성자의 인자로 excutor 라는 함수를 이용한다.
- excutor 함수는 resolve와 reject를 인자로 가진다. (resolve, reject ) => {...}
- resolve와 reject는 함수다. resolve(), reject()
- 생성자를 통해서 프로미스 객체를 만드는 순산 pending(대기) 상태라고 한다.
new Promise(/*excutor */(resolve,reject) => {});
- excutor 함수 인자 중 하나인 resolve 함수를 실행하면, fulfilled(이행) 상태가 된다.
new Promise((resolve,reject) => {
//Pending
//처리
resolve(); //fulfilled
});
- excutor 함수 인자 중 하나인 reject 함수를 실행하면, rejected (거부) 상태가 된다.
new Promise((resolve,reject) => {
reject(); //rejected
});
/*
p 라는 프로미스 객체는 1000ms 후에 fulfilled 된다.
fulfilled 되는 시점에, p.then 안에 설정한 callback 함수가 실행된다.
*/
const p = new Promise((resolve, reject)=>{
// Pending
setTimeout(()=>{
resolve(); //fullfilled
},1000);
});
p.then((/*callback*/)=>{
})
02. Promise-2
- p.then 으로 callback 함수를 지정했기 때문에 fulfilled 되면서 callback이 실행된다.
const p = new Promise((resolve, reject)=>{
// Pending
setTimeout(()=>{
resolve(); //fullfilled
},1000);
});
p.then(()=>{
console.log('1000ms 후에 fulfilled된다.')
})
- then을 설정하는 시점을 명확히 하고, 함수의 실행과 동시에 프로미스 객체를 만들면서 pending이 시작하도록 하기 위해 프로미스 객체를 생성하면서 리턴하는 함수 (p)를 만들어 함수(p) 실행과 동시에 then을 설정한다.
function p(){
return new Promise((resolve, reject)=>{
// Pending
setTimeout(()=>{
resolve(); //fullfilled
},1000);
});
}
p().then(()=>{
console.log('1000ms 후에 fulfilled 됩니다.');
});
- promise 객체가 rejected 되는 시점에 p.catch 안에 설정한 callback 함수가 실행된다.
function p(){
return new Promise((resolve, reject)=>{
// Pending
setTimeout(()=>{
reject(); //rejected
},1000);
});
}
p().then(()=>{
console.log('1000ms 후에 fulfilled 됩니다.');
}).catch(()=>{
console.log('1000ms 후에 rejected 됩니다.');
});
- excutor의 resolve 함수를 실행할 때 인자를 넣어 실행하면, then의 callback 함수의 인자로 받을 수 있다.
function p(){
return new Promise((resolve, reject)=>{
// Pending
setTimeout(()=>{
resolve('hello'); //인자 넣기
},1000);
});
}
p().then((message)=>{ //message , 비동기...머..?
console.log('1000ms 후에 fulfilled 됩니다.',message);
}).catch(()=>{
console.log('1000ms 후에 rejected 됩니다.');
});
- excutor의 reject 함수를 실행할 때 인자를 넣어 실행하면, catch의 callback 함수의 인자로 받을 수 있다.
function p(){
return new Promise((resolve, reject)=>{
// Pending
setTimeout(()=>{
reject('error') //인자 넣기
},1000);
});
}
p().then((message)=>{
console.log('1000ms 후에 fulfilled 됩니다.',message);
}).catch((reason)=>{
console.log('1000ms 후에 rejected 됩니다.', reason);
});
- error 객체 사용
function p(){
return new Promise((resolve, reject)=>{
// Pending
setTimeout(()=>{
reject(new Error('bad')) //인자 넣기
},1000);
});
}
p().then((message)=>{
console.log('1000ms 후에 fulfilled 됩니다.',message);
}).catch((error)=>{
console.log('1000ms 후에 rejected 됩니다.', error);
});
03. Promise-3
- fulfilled되거나 rejected된 후에 최종적으로 실행할 것이 있다면, .finally()를 설정하고, 함수를 인자로 넣는다.
function p(){
return new Promise((resolve, reject)=>{
// Pending
setTimeout(()=>{
reject(new Error('bad')) //인자 넣기
},1000);
});
}
p().then((message)=>{
console.log('1000ms 후에 fulfilled 됩니다.',message);
})
.catch((error)=>{
console.log('1000ms 후에 rejected 됩니다.', error);
})
.finally(()=>{
console.log('end');
});
- 보통 비동기 작업을 할 때, callback 함수를 인자로 넣어 로직이 끝나면 callback 함수를 호출한다. 이런 경우 함수가 아래로 진행되지 않고, callback 함수 안으로 진행된다.
function c(callback){
setTimeout(()=>{
callback();
},1000);
}
c(()=>{
console.log('1000ms후에 callback 함수가 실행')
});
c(()=>{
c(()=>{
c(()=>{
console.log('3000ms후에 callback 함수가 실행')
});
});
});
-then 함수에서 다시 프로미스 객체를 리턴하는 방법을 통해 체이닝 하면, 비동기 작업을 순차적으로 아래로 표현할 수 있다. then에 함수를 넣는 여러 방법을 확인해보자.
function p(){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve();
},1000);
});
}
p().then(()=>{ //p()에서 1초 걸림, .then()에서 1초 뒤
return p();
})
.then (()=>p()) //2초뒤
.then(p) //43초 뒤
.then(()=>{ //4초뒤
console.log('4000ms 뒤에 fulfilled된다.')
})
04. Promise-4
- value 가 프로미스 객체인지 아닌지 알 수 없는 경우, 사용하면 연결된 then 메서드를 실행한다.
value가 프로미스 객체면, resolve된 then 메서드를 실행
value가 프로미스 객체가 아니면, value를 인자로 보내면서 then 메서드를 실행한다.
Promise.resolve(/* value */);
Promise.resolve(new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('foo');
},1000);
})).then((data)=>{
console.log('프로미스 객체인 경우, resolve된 결과를 받아서 then이 실행',data);
});
Promise.resolve('bar').then(data =>{
console.log('then 메서드가 없는 경우, fulfilled 된다.',data);
})
- Promise.reject 를 사용하면, catch로 연결된 rejected 상태로 변경된다.
Promise.reject(/* value */);
Promise.reject(new Error('reason'))
.then(error=>{})
.catch(error=>{
console.log(error);
});
- 프로미스 객체를 여러개 생성하여, 배열로 만들어 인자로 넣고 Promise.all을 실행하면, 배열의 모든 프로미스 객체들이 fulfilled 되었을 때, then의 함수가 실행된다. then의 함수의 인자로 프로미스 객체들의 resolve 인자값을 배열로 돌려준다.
//Promise.all([프로미스 객체들]);
function p(ms){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve();
},ms);
})
}
Promise.all([p(1000), p(2000), p(3000)]).then(()=>{
console.log('모두 fulfilled된 이후에 실행됩니다.');
});
- 프로미스 객체를 여러개 생성하여, 배열로 만들어 인자로 넣고 Promise.race를 실행하면, 배열의 모든 프로미스 객체들중 가장 먼저 fulfilled 된 것으로, then의 함수가 실행된다. then의 함수의 인자로 가장 먼저 fulfilled된 프로미스 객체의 resolve 인자값을 돌려준다.
//Promise.all([프로미스 객체들]);
function p(ms){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(ms);
},ms);
})
}
Promise.race([p(1000), p(2000), p(3000)]).then((message)=>{
console.log('모두 fulfilled된 이후에 실행됩니다.',message);
});
2. async function과 await
01.async function과 await-1
async function 함수이름(){}
const 함수이름 = async() => {}
// Promise 객체를 리턴하는 함수
function p(ms){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(ms);
},ms);
});
}
// Promise 객체를 이용해서 비동기 로직을 수행할 때
p(1000).then(ms =>{
console.log(`${ms} ms후에 실행된다.`);
});
// Promise 객체를 리턴하는 함수를 await 로 호출하는 방법
const ms = await p(1000);
console.log(`${ms} ms후에 실행된다.`);
//SyntaxError: await is only valid in async function
- await를 사용하는 경우, 항상 async 함수 안에서 사용되어야한다.
function p(ms){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(ms);
},ms);
});
}
(async function main(){
const ms = await p(1000);
console.log(`${ms} ms 후에 실행된다.`);
})();
- Promise 객체가 rejected된 경우의 처리를 위해 try catch를 이용
function p(ms){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
reject(new Error('reason'));
},ms);
});
}
(async function main(){
try{
const ms = await p(1000);
}
catch(error){
console.log(error);
}
})();
- async function에서 return 되는 값은 Promise.resolve 함수로 감싸서 리턴된다.
function p(ms){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
reject(new Error('reason'));
},ms);
});
}
async function asyncP(){
return 'Mark';
}
(async function main(){
try{
const name = await asyncP();
console.log(name);
}
catch(error){
console.log(error);
}
})();
//Mark 출력
02.async function과 await-2
- async 에서 await p(1000)로 부르기 -> resolve
function p(ms){
return new Promise((resolve,reject)=>{
setTimeout(()=>{ //진행
resolve(ms);
// reject(new Error('reason'));
},ms);
});
}
async function asyncP(){
const ms = await p(1000); //P를 먼저 해결하러 떠남
return 'Mark: '+ ms;
}
(async function main(){
try{
const name = await asyncP();
console.log(name);
}
catch(error){
console.log(error);
}
})();
//Mark: 1000 출력
- async 에서 await p(1000)로 부르기 -> reject
function p(ms){
return new Promise((resolve,reject)=>{
setTimeout(()=>{ //진행
// resolve(ms);
reject(new Error('reason'));
},ms);
});
}
async function asyncP(){
const ms = await p(1000); //P를 먼저 해결하러 떠남
return 'Mark: '+ ms;
}
(async function main(){
try{
const name = await asyncP();
console.log(name);
}
catch(error){ //error
console.log(error);
}
})();
//에러 호출
-try,catch, finally 사용
function p(ms){
return new Promise((resolve,reject)=>{
setTimeout(()=>{ //진행
resolve(ms);
// reject(new Error('reason'));
},ms);
});
}
async function asyncP(){
const ms = await p(1000); //P를 먼저 해결하러 떠남
return 'Mark: '+ ms;
}
(async function main(){
try{
const name = await asyncP();
console.log(name);
}
catch(error){ //error
console.log(error);
}
finally{
console.log('end');
}
})();
- 비동기 처리를 Promise와 async await비교
function p(ms){
return new Promise((resolve,reject)=>{
setTimeout(()=>{ //진행
resolve(ms);
// reject(new Error('reason'));
},ms);
});
}
//Promise
p(1000),then(()=>p(1000)).then(()=>p(1000)).then(()=>{
console.log('3000ms 후에 실행');
});
//async await
(async function main(){
await p(1000);
await p(1000);
await p(1000);
console.log('3000ms 후에 실행');
})();
- Promise.all 과 Promise.race
function p(ms){
return new Promise((resolve,reject)=>{
setTimeout(()=>{ //진행
resolve(ms);
// reject(new Error('reason'));
},ms);
});
}
/*Promise.all
(async function main(){
const results = await Promise.all([p(1000),p(2000),p(3000)]);
console.log(results); //[ 1000, 2000, 3000 ]출력
})();
*/
//Promise.race
(async function main(){
const results = await Promise.race([p(1000),p(2000),p(3000)]);
console.log(results); //1000 출력
})();
'Front-end > Web' 카테고리의 다른 글
[JS] 콘솔에 출력, script async와 defer의 차이점 및 공부방향 (0) | 2021.08.26 |
---|---|
[JS] 자바스크립트의 역사와 현재 그리고 미래 (0) | 2021.08.26 |
JavaScript 기초 - 객체, 클래스 (0) | 2021.02.23 |
JavaScript 기초 - 조건문, 반복문, 함수 (0) | 2021.02.23 |
JavaScript 기초 - 시작, 변수 (0) | 2021.02.23 |
댓글