자바스크립트는 동기적(Synchronous) 언어입니다.
한 번에 하나의 작업을 수행해요.
키오스크를 이용하여 한 사람씩 결제하는 느낌이랄까요?
이러한 동작을 단일 스레드(싱글 스레드), 동기(Synchronous)
라고 해요.
Hoisting 된 후 작성한 순서에 맞춰 동기적으로 실행됩니다.
잠깐 Hoisting??
- 코드가 실행하기 전 var, function declaration이 제일 위로 올라가요.
- 변수선언 / 함수선언 이 해당 스코프의 최상단으로 끌어 올려진 것 같은 현상을 말해요.
🤔왜 비동기가 필요한가요?
웹 페이지가 로딩되거나, 어떠한 동작(Event) 하나가 30초 이상이 걸린다고 상상해봐요
동기적
으로 하면 웹 페이지는 이 동작이 끝날 때까지 화면에 나타나지 않거나 다음 동작을 수행하는데 지장을 주게 됩니다.
또, 사용자들은 빠른 응답을 주는 웹 사이트를 원하죠?
그렇기 때문에 자바스크립트가 웹 사이트에서 동작할 때, 비동기적으로 동작할 수 있어야 해요.
어떤 일의 진행 상태를 나타내는 객체로
진행 상태와 값
이라는 속성을 가지고 있어요.
진행 상태 : pending → fulfilled or rejected
resolve, reject
는 함수입니다.
const promise = new Promise((resolve, reject)=>{
// doing heavy work
// 성공 시
resolve("성공했어요.");
// 실패 시
reject(new Error('실패했어요.'));
});
promise
.then(value => console.log(value)) // resolve를 받음
.catch(err => console.log(err)); //reject를 받음
Promise를 깔끔하게 사용할 수 있어요.
new Promise
객체를 사용하지 않아도 Promise를 반환해요.
Promise인 경우
function fetchUser() {
//10초씩이나 걸리는 작업;
return new Promise((resolve,reject)=>{
resolve('나인');
})
}
fetchUser().then((who)=>console.log(who))
console.log('두두등장');
async로 바꾼 경우
async function fetchUser() {
// 10초씩이나 걸리는 작업;
return '나인';
}
fetchUser().then((who)=>console.log(who));
console.log('두두등장');
async가 붙은 함수 내에서만 쓸 수 있어요.
동기 함수든 비동기 함수든 앞에 붙일 수 있어요.
await
키워드를 앞에 붙이면 해당 함수가 실행을 끝낼 때까지 다음 코드는 동작하지 않아요.
아래는 MDN 예시예요.
Promise만 쓰면..
// then으로 자꾸 콜백을 해야해요ㅠㅠ
fetch('coffee.jpg')
.then(response => response.blob())
.then(myBlob => {
let objectURL = URL.createObjectURL(myBlob);
let image = document.createElement('img');
image.src = objectURL;
document.body.appendChild(image);
})
.catch(e => {
console.log('There has been a problem with your fetch operation: ' + e.message);
});
async / await를 쓰면..
// await는 async가 붙은 함수 내에서만 쓸수 있다고 했죠?
async function myFetch() {
let response = await fetch('coffee.jpg'); // 오래 걸리니 기다려 주세요.
let myBlob = await response.blob(); // 오래 걸리니 기다려 주세요.
let objectURL = URL.createObjectURL(myBlob);
let image = document.createElement('img');
image.src = objectURL;
document.body.appendChild(image);
}
// 호출해볼까요.
myFetch()
.catch(e => {
console.log('There has been a problem with your fetch operation: ' + e.message);
});