[Pre Onboarding] 8월 9일
- callback 패턴과 문제점은?
- promise와 callback의 차이점은 무엇이고 각각 장단점은?
- promise란 무엇인가
- Promise.all 은 언제 쓰이는지?
- async/await와 promise의 차이는?
동기(Synchronouse)
정의 : 현재 실행중인 코드가 끝나야 다음 코드를 실행
현재 실행중인 task가 종료할 때까지 다음 task가 대기하는 방식
->순서대로 실행, 너무 당연한 이야기이다.
고민할 점
장점 : 동기 처리는 코드를 순서대로 하나씩 실행하기 때문에, 실행 순서가 보장된다.
단점 : 현재 실행중인 task가 종료할 때까지, 다음 task가 대기하는 방식
alert가 전형적인 동기 함수이다.
-> 확인 버튼을 사용자가 눌러야 함수 끝난다.
누르기 전까지는 bloking되면서 멈춰있다.
비동기(Asynchronouse)
정의
현재 실행중인 코드가 완료되지 않아도, 다음 코드로 넘어감
비동기 task는 실행하라고 브라우저에 맡겨놓고, 다음 task로 넘어감
api호출하고 언제 응답이 올지는 모름
고민할점
장점 : 현재 실행중인 task가 완료되지 않아도, 다음 task를 실행하기 때문에 블로킹이 발생하지 않는다.
단점 : task의 실행 순서가 보장되지 않는다.
프론트에서의 비동기 로직
비동기 처리가 필요한 이유
*AJAX(Asynchronous JavaScript and XML) 비동기 자바스크립트 와 XML
예전에는 xml(데이터 형식중하나)을 받아 화면에 전체적으로 그린다.
비동기적으로 API를 호출해서 원할때 필요한 부분만 바꾼다가 안되었음
정의 : 자바스크립트를 사용해서 브라우저가 서버에게 비동기 방식으로 데이터를 요청하고
응답한 데이터를 수신하여 웹페이지를 일부 동적으로 갱신하는 것.
fetch, awake 다 ajax
동기, 비동기 관련 키워드(연관되어 공부하자.)
정의 : 함수의 매개변수가 함수일 때 매개변수로 받은 함수를 콜백함수라고 부른다!!!
참고 : 링크텍스트
Promise -> 클래스이다 대문자
Promise 구현하기
let promise = new Promise(function(**resolve**, **reject**) {
// 여기 비동기 로직을 작성하는것! 시키고 나중에 하고 싶은 로직 작성
// 시켜놓고 언제 완료될지 모르는 로직!
});
resolve는 성공했을 때 실행할 함수(콜백함수)
reject는 실패했을 때 실행할 함수(콜백함수)
참고로, resolve, reject 미리 정의하지 않아도 자바스크립트 엔진에서 미리 정의 해놓는다.
그래서 전달 안해도 호출에 문제 없음.
```jsx
let promise = new Promise(function(resolve, reject) {
resolve(); // 에러 안 납니다.
reject();
console.log('실행 됨');
});
```
예제
let promise = new Promise(function(resolve, reject) {
// 여기 비동기 로직을 작성!
// 시켜놓고 언제 완료될지 모르는 로직!
// 완료 하면 -> resolve 호출
// 비동기 동작 실패 하면 -> reject 호출
});
promise.then(function() {
// 이 함수가 바로 위의 resolve 입니다.
// 위의 비동기 로직이 성공하면 호출 됩니다!
});
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!
});
let promise = new Promise(function(resolve, reject) {
});
// then 인자 둘 다 cb 함수
// 첫 번째는 성공했을 때 실행할 resolve 함수 정의
// 두 번째는 실패했을 때 실행할 reject 함수 정의
promise.then(function() {}, function() {});
let promise = new Promise(function(resolve, reject) {
setTimeout(function() {
// 실패한 건 아니지만, 실패했다고 가정하고 reject 호출
reject('으악!');
}, 2000);
});
promise.then(function() {
console.log('resolve');
}, function(msg) {
console.log('reject', msg);
});
// 요런 느낌
getProducts() // 상품 가져오고
.then(getComments) // 그리고 후기 가져오고(끝나고 실행)
.then(getLikes) // 그리고 좋아요 가져오고(끝나고 실행)
then의 콜백함수(handler function 이라고도 함)는 여러 타입의 값을 반환할 수 있다.
값의 반환
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);
});
promise 반환
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', second);
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(3);
}, 1000);
});
})
.then(function(third) {
console.log('third', third);
});
리턴값이 일반값이면 다음 then에서 매개변수로, promise면 그 다음 then이 resolve가 된다.
Promise로 바꾸기
$.get('https://api.test.com/proudcts', function(response) {
var firstProductId = response.products[0].id;
$.get('https://api.test.com/proudct/comments?id='+firstProductId, function(response) {
var firstCommentId = response.comments[0].id;
$.get('https://api.test.com/proudct/comment/likes?id='+firstCommentId, function(response) {
var likes = response.likes;
var likesCount = likes.length;
// 첫번째 상품의 -> 첫번째 후기의 좋아요 수 화면에 적용!
});
});
});
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;
});
let promise = new Promise(function(resolve, reject) {
setTimeout(function() {
reject('으악!');
}, 2000);
});
promise.then(function() {}, function(msg) {
console.log(msg);
});
let promise = new Promise(function(resolve, reject) {
setTimeout(function() {
reject('으악!');
}, 2000);
});
promise
.then(function() {})
.catch(function(err) {
console.log(err);
});
혼자 공부해보기
여러 프로미스를 다 하고 그다음에 하고 싶은 경우
Promise.all([
new Promise(resolve => setTimeout(() => resolve(1), 9000)), // 1
new Promise(resolve => setTimeout(() => resolve(2), 2000)), // 2
new Promise(resolve => setTimeout(() => resolve(3), 1000)) // 3
]).then(console.log);
이럴때 많이 사용한다/
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}`)
));
async & await 관련 키워드