8/12(목) 프리온보딩 수업내용을 정리한 내용 입니다.
지금 실행중인 task 가 종료될 때까지, 다음 task 가 대기하는 방식
장점 👉🏻 실행 순서가 보장된다.
단점 👉🏻 지금 task가 종료될때까지 다음 task 가 실행 될 수 없다. (blocking 된다 라고 표현)
비동기 task는 실행하라고 브라우저에 맡겨놓고, 다음 task로 넘어감
장점 👉🏻 블로킹(blocking)이 발생하지 않는다.
단점 👉🏻 task 실행 순서가 보장 되지 않는다.
비동기 처리가 필요한 이유
자바스크립트 엔진은 한번에 한번의 task 만 실행할 수 있는 single Thread(싱글쓰레드),
처리시간이 걸리는 task를 실행하는 경우 Blocking(작업중단)이 발생할 수 있다.
콜백함수의 등장
비동기를 처리하기 위해 전통적으로 콜백패턴(레거시적 방법)을 사용한다.
AJAX 자바스크립트를 사용하여 브라우저가 서버에게 비동기 방식으로 데이터를 요청하고,
응답한 데이터를 수신하여 웹페이지를 일부 동적으로 갱신한다.
setTimeout(()=>{
console.log("1")
},0)
console.log('2')
for(let i =0; i<3; i++){
loop();
}
setTimeout(()=>{
console.log("3")
},0)
console.log('4')
function loop(){
console.log("5")
}
정답
"2","5","5","5","4","1","3"
비동기는 동기호출 이후 호출된다.
함수의 매개변수가 함수일때, 그 매개변수를 콜백함수라 한다.
HOC(고차함수) 👉 매개변수를 함수로 받은 함수, 인자를 컨포넌트로 받아서 컴포넌트를 반환하는 것.
function showMessage(message, closeFn){
closeFn(true)
}
// showMessage : 고차함수
// closeFn : 콜백함수
[1,2,3].map(el => el*2)
//< el=>el*2 자체를 콜백함수라 함
단, 콜백함수라 해서 항상 비동기에 쓰이진 않는다.
callback안에 callback이 계속 이어지는 모습인 콜백지옥 패턴을 나타낼 수 있다.
비동기 동작을 처리 하기 위해 도입 (ES6)
Promise 👉 javascript 내장 클래스
클래스 👉 객체 만드는 공장, 객체를 만들때 그것을 인스턴스 한다고한다.
state, resolve, reject, finally 함수 이해하기
x
let promise = new Promise(function(resolve, reject){
});
let promise = new Promise(function(resolve, reject) {
resolve();
reject();
console.log('실행 됨');
});
// new Promise 로 객체를 생성해 promise 에 넣어둔 것!
let promise = new Promise(function(resolve, reject){
// 여기 비동기 로직 작성
// 완료하면 => resolve 호출
// 비동기 동작 실패 하면 => reject 호출
});
promise.then(function(){
// 이 함수가 바로 위의 resolve
// 위의 비동기 로직이 성공하면 호출 됩니다!
});
promise.finally(function(){
//finally() 메소드는 Promise 객체를 반환합니다.
//Promise가 처리되면 충족되거나 거부되는지 여부에 관계없이
//지정된 콜백 함수가 실행됩니다.
// settled (fulfilled or rejected)
});
-----------------------
let promise = new Promise(function(resolve, reject) {
setTimeout(function() {
// resolve 함수에 인자 넘기면
resolve('hello world');
}, 2000);
});
// resolve로 넘기는 콜백함수의 매개변수로 받을 수 있다.
promise.then(function(msg) {
console.log(msg);
// 2초 뒤에 hello world!가 출력됩니다.
});
// new Promise 로 객체를 생성해 promise 에 넣어둔 것!
let promise = new Promise(function(resolve, reject){
// 여기 비동기 로직 작성
// 완료하면 => resolve 호출
// 비동기 동작 실패 하면 => reject 호출
});
promise.then(function(){
// 이 함수가 바로 위의 resolve
// 위의 비동기 로직이 성공하면 호출 됩니다!
}, function(){
// 이 함수가 바로 위의 reject
// 위의 비동기 로직이 실패하면 호출 됩니다!
});
---------------------------------
let promise = new Promise(function(resolve, reject) {
setTimeout(function() {
// resolve 함수에 인자 넘기면
reject('ERROR');
}, 2000);
});
// resolve로 넘기는 콜백함수의 매개변수로 받을 수 있다.
promise.then(function() {
console.log('resolve');
}, function(msg){
console.log('reject', msg);
});
// 출력값 reject , ERROR
let promise = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(1);
resolve(2);
}, 1000);
});
promise.then(function(msg) {
console.log(msg); //1
});
// 한번 호출 하면 then 속으로 들어가서 다시 돌어가지 않는다.
let promise = new Promise(function(resolve, reject) {
setTimeout(function() {
console.log(1);
resolve(2);
console.log(3);
resolve(4);
}, 1000);
});
promise.then(function(data) {
console.log(data);
});
// 출력값 1,3,2
-------------------------------------------------------
let promise = new Promise(function(resolve, reject) {
resolve(1);
setTimeout(function () {
resolve(2);
}, 1000);
});
promise.then(function(data) {
console.log(data);
});
// 1
여러 개의 비동기 작업을 순차적으로 해야하는 경우가 많다.
let promise = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(1);
}, 1000);
});
promise
.then(function(first) {
console.log('first', first);
return 2;
}).then(function(second) {
console.log(second);
});
// 출력값 'first' , 1 , 2
// then 자체가 promise를 반환한다고 볼 수 있다.
리턴값이 일반값이면 다음 then에서 매개변수로, promise면 그 다음 then이 resolve가 된다.
function job() {
return new Promise(function(resolve, reject) {
reject();
});
}
job()
.then(function() {
console.log(1);
})
.then(function() {
console.log(2);
})
.then(function() {
console.log(3);
})
.catch(function() {
console.log(4);
})
.then(function() {
console.log(5);
});
// 4,5
function job(state) {
return new Promise(function(resolve, reject) {
if (state) {
resolve('success');
} else {
reject('error');
}
});
}
job(true)
.then(function(data) {
console.log(data);
return job(false);
})
.catch(function(error) {
console.log(error);
return 'Error caught';
})
.then(function(data) {
console.log(data);
return job(true);
})
.catch(function(error) {
console.log(error);
});
// 출력값 success > error > Error caught > success
let urls = [
'https://api.github.com/users/iliakan',
'https://api.github.com/users/remy',
'https://api.github.com/users/jeresig'
];
// map every url to the promise of the fetch
let requests = urls.map(url => fetch(url));
// Promise.all waits until all jobs are resolved
Promise
.all(requests)
.then(responses => responses.forEach(
response => alert(`${response.url}: ${response.status}`)
));
// 배열 형태로 반환된다.
promise.all은 작업들이 다 끝난이후 배열로 반환되는 반면,
promise.race 는 가장 먼저 완료된 것을 결과값으로 반환하는 함수이다.(하나라도 이행 또는 거부상태일때 완료함)
promise.all 의 경우 거부상태가 있을때 바로 반환 🚂
(function () {
// 내용
})();
(() => {
// 내용
})();
(async function() {
// 내용
})();
(async () => {
// 내용
})();
react useEffect 안에서 활용 될 수 있다.🚦
useEffect 훅 안에서 비동기 사용하기
(async () => {
try {
let productResponse = await fetch('https://api.test.com/proudcts');
let firstProductId = productResponse.products[0].id;
let commentResponse = await fetch('https://api.test.com/proudct/comments?id='+firstProductId);
let firstCommentId = commentResponse.comments[0].id;
let likeResponse = await fetch('https://api.test.com/proudct/comment/likes?id='+firstCommentId);
let likesCount = likeResponse.likes.length;
} catch(error) {
console.log(error);
}
})();
Promise 관련 면접 예상질문
- promise와 callback의 차이점은 무엇이고 각각 장단점은?
- promise란 무엇인가
- Promise.all 은 언제 쓰이는지?
- async/await와 promise의 차이는?
비동기와 동기 관련된 주제는 실제 업무중에도 정말 많이 사용 되고 여러 오픈소스에서도 쉽게 사용되는것을 찾을 수 있지만, 깊게 들어가다보면 헷갈리거나 복잡한 부분이 많이 있다.
간단한 것 같지만 여러가지 방식으로 사용될 수 있기 때문에 계속해서 공부하며 활용 하는 연습을 하기!
이미 알고 있던 내용도 있었지만 프리온보딩 수업 이후 더욱 확실이해하게되고 헷갈릴 수 있는 개념들을 콕콕 집어주셔서 머리속에 명확하게 정리 할 수 있어 좋았다.
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise/finally
https://www.notion.so/wecode/Core-JavaScript-1-b649b11a990148228ba61ea4c4f4efb0
안녕하세요 덕분에 Promise에 대해 조금 더 알게 되었어요!
저같은 응애 개발자들도 이해하기 쉽게 알려주셔서 좋네요ㅎㅎ
그런데 한가지 했갈리는? 질문이 있는데요 "reject 이해하기" 부분에서 resolve에 전달한다고 하셨는데 이 부분은 단순 오타인건가요?
그게 아니라면 혹시 왜 reject가 아니라 resolve에 전달되어야하는건가요??