1 Callback
- 다른 함수에 인수로 전달된 함수
- 외부 함수 내부에서 호출되어 일종의 루틴이나 작업을 완료
- 비동기 작업이 완료된 후 코드 실행을 계속하기 위해 자주 사용됨(비동기 콜백)
1) Callback 흐름 제어 유형
- 동기식
- 호출부에서 실행 결과가 리턴될 때 까지 기다려야 하는 함수
- 비동기식
- 호출부에서 실행 결과를 가다리지 않아도 되는 함수
- 싱글 쓰레드 환경에서 실행되는 언어에서 광범위하게 사용
- 순차적 처리가 보장되지 않기 때문에 아래에 위치한 코드가 위에 위치한 코드보다 먼저 실행될 수 있음
- 동기 함수에 비해서 좀 덜 직관적으로 느껴짐
2) setTimeout()
- 코드를 바로 실행하지 않고 일정 시간 기다린 후 실행해야하는 경우에 사용하는 함수
setTimeout(() => console.log("2초 후에 실행됨"), 2000);
//"2초 후에 실행됨" 출력
3) setInterval()
- 어떤 코드를 일정한 시간 간격을 두고 반복해서 실행하고 싶을 때 사용
setInterval(() => console.log(new Date()), 2000);
// 콘솔에 현재 시간을 2초마다 출력
2 Promise
- 비동기 작업이 끝난 후 결과를 알려주는 용도로 사용되는 객체
- 최종 결과를 반환하는 것이 아니고, 미래의 어떤 시점에 결과를 제공하겠다는 '약속'(프로미스)을 반환
1) Promise 상태의 종류
- 대기(pending) : 이행하지도, 거부하지도 않은 초기 상태
- 이행(fulfilled) : 연산이 성공적으로 완료됨
- 거부(rejected) : 연산이 실패함
3 Async & Await
async function name([param[, param[, ... param]]]) {
statements
}
- name : 함수의 이름
- param : 함수에게 전달되기 위한 인자의 이름
- statements : 함수 본문을 구성하는 내용
- 반환값 : Promise (async 함수에 의해 반환 된 값으로 해결되거나 async함수 내에서 발생하는 캐치되지 않는 예외로 거부되는 값)
1) Await
- Async 함수 내에 포함될 수 있는 식
- 함수의 실행을 일시 중단하고 전달된 Promise의 해결( fulfill, reject)을 기다린 다음 async 함수의 실행을 다시 시작하고 완료후 값을 반환함
- 목적 : 여러 promise의 동작을 동기스럽게 사용할 수 있게 하고, 어떠한 동작을 여러 promise의 그룹에서 간단하게 동작하게 하는 것
- 반환값
- fulfill→ Promise에서 fulfill된 값
- reject → 값 버림
4 실습
//------------------------------------------------
// 데이터 통신에서의 활용
const posts = [
{ post_id : 1, post_title: " 첫번쨰 글 " },
{ post_id : 2, post_title: " 두번쨰 글 " },
{ post_id : 3, post_title: " 세번쨰 글 " },
];
const comments = [
{ post_id : 1, comment_id : 1, comment : "첫번쨰 글 첫번쨰 코멘트" },
{ post_id : 2, comment_id : 1, comment : "두번쨰 글 첫번쨰 코멘트" },
{ post_id : 2, comment_id : 2, comment : "두번쨰 글 두번쨰 코멘트" },
{ post_id : 2, comment_id : 3, comment : "두번쨰 글 세번쨰 코멘트" },
{ post_id : 3, comment_id : 1, comment : "세번쨰 글 첫번쨰 코멘트" },
{ post_id : 3, comment_id : 2, comment : "세번쨰 글 두번쨰 코멘트" },
];
const postNum = 2;
// id가 posts 배열에 있는지 확인하여 참일 경우 post에 담기, 실패했을 경우 error 메세지 출력
const getPost = (id, onSuccess, onError) => {
setTimeout( () => {
const post = posts.find(post => post.post_id === id);
if(post) {
onSuccess(post.post_id);
} else {
onError("찾는 포스트 없다");
}
}, 3000)
}
const getComments = (post_id, onSuccess, onError) => {
setTimeout( () => {
const result = comments.filter(comment => comment.post_id === post_id);
if(result.length > 0) {
onSuccess(result);
} else {
onError("찾는 포스트 없다");
}
}, 4000)
}
//콜백지옥 : 가독성이 떨어짐 - Promise, async
getPost(postNum, (postId) => { console.log('Post', postId);
getComments (postId,
(result) => { console.log('Comments:' , result) },
(message) => { console.log(message);}
)
},
(message) => { console.log(message); }
)
const posts = [
{ post_id : 1, post_title: " 첫번쨰 글 " },
{ post_id : 2, post_title: " 두번쨰 글 " },
{ post_id : 3, post_title: " 세번쨰 글 " },
];
const comments = [
{ post_id : 1, comment_id : 1, comment : "첫번쨰 글 첫번쨰 코멘트" },
{ post_id : 2, comment_id : 1, comment : "두번쨰 글 첫번쨰 코멘트" },
{ post_id : 2, comment_id : 2, comment : "두번쨰 글 두번쨰 코멘트" },
{ post_id : 2, comment_id : 3, comment : "두번쨰 글 세번쨰 코멘트" },
{ post_id : 3, comment_id : 1, comment : "세번쨰 글 첫번쨰 코멘트" },
{ post_id : 3, comment_id : 2, comment : "세번쨰 글 두번쨰 코멘트" },
];
const postNum = 1;
// * Promise *
// pending 진행중
// fulfilled 성공적으로 끝남
// rejected 실패로 끝남
// new Promise(resolve, reject)
const getPost = (id) => {
return new Promise((resolve, reject) => {
setTimeout( () => {
const post = posts.find((post) => post.post_id === id);
if (post) {
resolve(post.post_id);
} else {
reject("찾는 포스트 없다");
}
}, 3000);
} );
};
const getComments = (post_id) => {
return new Promise((resolve, reject) => {
setTimeout( () => {
const result = comments.filter((comment) => comment.post_id === post_id);
if (result.length > 0) {
resolve(result);
} else {
reject("찾는 포스트에 코멘트가 없다");
}
}, 4000);
} );
};
// .then 성공 , .catch 실페 결과 반환
// getPost(postNum)
// .then(postId => {
// console.log('Post : ', postId)
// return getComments(postId)
// })
// .then(result => console.log('Comments :', result))
// .catch(message => console.log(message));
// retern을 삭제하면 Comments가 선언되지 않았다고 뜸
// 제대로 실행되면 resolve 아니면 reject
// 두 줄 이상이면 return을 써줘야함
//-------------------------------------------------------
// async await : 비동기적인 것을 동기적으로 느끼게 함, 직관적
async function getResult() {
const postId_result = await getPost(postNum);
const comments_result = await getComments(postId_result);
console.log("Post:", postId_result, "Comments:", comments_result);
}
getResult();