// blocking 예시 const arr = []; for (let i = 0; i < 1000; i++) { arr.push(i); // 1000번 반복하면서 실행할 더더더더더 복잡한 코드 } alert("안녕하세요); // 확인 누를 때까지 console 안나옴 console.log(arr);
브라우저
에 맡겨놓고, 다음 task로 넘어감// 화면 그리기 1 axios.get(url) .then(response => { // api 호출하고 응답받으면 실행 }) // 화면 그리기 2 // 다른 로직~~
- 화면그리기 1 하고,
- axios api 호출하고 (언제 응답이 올지는 모름)
- 화면그리기 2 하다가
- 응답이 오면 로직을 실행하고,
- 다시 다른 로직 진행한다.
// [1] 콜백함수 예시 => 동기 함수 => closeFn이 콜백함수! function showMessage(msg, closeFn) { closeFn(true); } // [2] 콜백함수 예시 => 동기 함수 => map 함수의 인자 el => el*2 함수가 콜백함수! [1,2,3].map(el => el*2); // [3] 콜백함수 예시 => 비동기 함수 => e => {} 함수가 콜백함수! window.addEventListener('keydown', e => { // 로직 }); // [4] 콜백함수 예시 => 비동기 함수 => setTimeout에 넘긴 익명함수가 콜백함수! setTimeout(function(){ alert("Hello"); }, 3000);
state
, resolve
, reject
함수를 이해하면 된다.
resolve
: 성공했을 때 실행할 함수
let promise = new Promise(function(resolve, reject) {
// 여기 비동기 로직을 작성!
// 시켜놓고 언제 완료될지 모르는 로직!
setTimeout(function() {
resolve('hello world');// resolve 함수에 인자 넘기면
}, 2000);
});
// resolve로 넘기는 콜백함수의 매개변수로 받을 수 있다.
promise.then(function(msg) {
console.log(msg); // 2초 뒤에 hello world!
});
reject
: 실패했을 때 실행할 함수
let promise = new Promise(function(resolve, reject) {
setTimeout(function() {
reject('으악!'); // 실패했다고 가정하고 reject 호출
}, 2000);
});
// then 인자 둘 다 cb 함수
// 첫 번째는 성공했을 때 실행할 resolve 함수 정의
// 두 번째는 실패했을 때 실행할 reject 함수 정의
promise.then(function() {
console.log('resolve');
}, function(msg) {
console.log('reject', msg);
});
Q1. Promise안에 resolve() 함수가 여러개 있으면 어떻게 동작할까?
let promise = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(1); // ✅ 첫 번째 resolve 만 실행됨
resolve(2);
}, 1000);
});
Q2. Promise안에 resolve(), reject() 함수가 여러개 있으면 어떻게 동작할까?
let promise = new Promise(function(resolve, reject) {
setTimeout(function() {
reject(1); // ✅ 첫 번째 reject 만 실행됨
resolve(2);
resolve(3);
}, 1000);
});
Q3. Promise안에 실행순서 맞추기!
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);
});
then의 콜백함수(=handler function)
는 여러 타입의 값을 반환할 수 있다.let promise = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(1);
}, 1000);
});
promise
.then(function(first) {
console.log('first', first); // ✅ 'first',1
return 22; //값 2를 리턴
})
.then(function(second) { //second에 22가 들어온다.
console.log('second', second); // ✅ 'second',22
return new Promise(function(resolve, reject) { // new Promise를 리턴
setTimeout(function() {
resolve(333);
}, 1000);
});
})
.then(function(third) {
console.log('third', third); // 1초 뒤 333 실행됨 // ✅ 'third', 333
});
promise 객체는 "상태"를 갖고 있다.
Pending(대기)
: 비동기 처리 로직이 아직 완료되지 않은 상태Fulfilled(이행)
: 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태Rejected(실패)
: 비동기 처리가 실패하거나 오류가 발생한 상태reject handler와 catch 방식은 똑같다. catch문이 가독성이 더 좋다.
let promise = new Promise(function(resolve, reject) {
setTimeout(function() {
reject('으악!');
}, 2000);
});
promise
.then(function() {})
.catch(function(err) { // ✅ catch
console.log(err);
});
Q1. console.log 정답은? ➡ 4,5
function job() {
return new Promise(function(resolve, reject) {
reject(); // reject를 실행
});
}
job()
.then(function() {
console.log(1);
})
.then(function() {
console.log(2);
})
.then(function() {
console.log(3);
})
.catch(function() {
console.log(4); // ✅ 4 출력
})
.then(function() {
console.log(5); // ✅ 5 출력
});
Q2. console.log 정답은? ➡ success, error, Error caught
function job(state) {
return new Promise(function(resolve, reject) {
if (state) {
resolve('success');
} else {
reject('error');
}
});
}
job(true)
.then(function(data) {
console.log(data); // ✅ job(true) 이므로 resolve 실행 && 'success' 출력
return job(false); // return 값으로 job(false) 반환
})
.catch(function(error) {
console.log(error); // ✅ job(false) 이므로 reject 실행 && 'error' 출력
return 'Error caught'; // return 값으로 string 반환
})
.then(function(data) {
console.log(data); // ✅ 'Error caught'값을 전달 받음 && 'Error caught' 출력
return job(true); // return 값으로 job(true) 반환
})
.catch(function(error) {
console.log(error); //-> job(true)의 resolve가 실행되므로 catch는 실행되지 않는다.
});
예제1 - Promise.all()
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}`)
));
예제2 - Promise.all() - 모든 promise가 resolve 될 때
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 3000, 'foo');
});
Promise.all([promise1, promise2, promise3]).then((values) => {
console.log(values); // 3초 뒤 > Array [3, 42, "foo"]
});
예제3 - Promise.all() - reject되는 promise가 있다면?
➡Promise.all()
은 배열 내 요소 중 어느 하나라도 거부하면 즉시 거부!!
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
setTimeout(reject, 3000, 'foo');
});
Promise.all([promise1, promise2, promise3]).then((values) => {
console.log(values); // 3초 뒤 > `all:1 Uncaught (in promise) foo` 에러반환
});
async
function은 ES8에 도입되었으며, 비동기 함수를 선언한다.
async
function은 promise를 반환한다.
await
를 쓰려면 async
함수 안에 꼭 있어야 한다!
(변경 전)
.then().then().then() ~ 가독성이 떨어진다.
axios('https://api.test.com/proudcts')
.then(function(response) {
let firstProductId = response.products[0].id;
return axios('https://api.test.com/proudct/comments?id='+firstProductId);
})
.then(function(response) {
let firstCommentId = response.comments[0].id;
return axios('https://api.test.com/proudct/comment/likes?id='+firstCommentId)
})
.then(function(response) {
let likes = response.likes;
let likesCount = likes.length;
});
(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);
}
})();
fetch
/axios
함수는 promise
를 반환한다axios()
와 new Promise()
는 똑같다.