async 함수
: await 키워드는 반드시 async 함수 내부에서 사용해야 한다. async 함수는 async 키워드를 사용해 정의하여 언제나 프로미스를 반환한다. async 함수가 명시적으로 프로미스를 반환하지 않더라도 async함수는 암묵적으로 반환값을 resolve하는 프로미스를 반환한다.
await
: 프로미스가 settled 상태가 될때까지 대기하다가 settled 상태가 되면 프로미스가 resolve 한 처리결과를 반환한다.
주의해야 한다. 너무 await을 남발하면 느려질 수 있다.
async function foo(){
const a = await new Promise(resolve=>setTimeout(()=>resolve(1),3000));//settled상태까지3
const b = await new Promise(resolve=>setTimeout(()=>resolve(2),2000));//2
const c = await new Promise(resolve=>setTimeout(()=>resolve(3),1000));//1초가 걸려
console.log([a,b,c])//총 6초가 걸림
}
//하지만, foo함수내 a,b,c는 순차적으로 처리할 필요가 없음
//Promise.all을 사용하자
async function foo(){
const res = await Promise.all([
new Promise(resolve=>setTimeout(()=>resolve(1),3000)),
new Promise(resolve=>setTimeout(()=>resolve(2),2000)),
new Promise(resolve=>setTimeout(()=>resolve(3),1000)),
]);
console.log(res); //[1,2,3]
}
foo(); //약 3초 소요된다.
//만약, b를 구하는데 a의 결과가 사용된다면 await으로 기다려야 함 nn
async function fetchAndDecode(url, type) {
let response = await fetch(url);
let content;
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
} else {
if(type === 'blob') {
content = await response.blob();
} else if(type === 'text') {
content = await response.text();
}
}
return content;
}
async function displayContent() {
//비동기 함수로 만듦
let coffee = fetchAndDecode('coffee.jpg', 'blob');
let tea = fetchAndDecode('tea.jpg', 'blob');
let description = fetchAndDecode('description.txt', 'text');
//이곳에서 동기로 하기에
let values = await Promise.all([coffee, tea, description]);
let objectURL1 = URL.createObjectURL(values[0]);
let objectURL2 = URL.createObjectURL(values[1]);
let descText = values[2];
let image1 = document.createElement('img');
let image2 = document.createElement('img');
image1.src = objectURL1;
image2.src = objectURL2;
document.body.appendChild(image1);
document.body.appendChild(image2);
let para = document.createElement('p');
para.textContent = descText;
document.body.appendChild(para);
}
displayContent()
.catch((e) =>
console.log(e)
);
async/await 동기식 코드처럼 보이게 한다.
함수 블럭에 여러 개의 await 키워드를 사용하면 Promise가 fulfiled 되기 전까지 다음 await을 차단한다.
그 동안 다른 태스크는 계속 실행이 되지만, 정의한 함수 내에서는 동기적으로 작동한다.
// 내가 이렇게 하고 있다.
(1) 비동기로 실행될 Promise가 있다면 async함수 안에 항상 await을 써야한다.
(2) 우리가 작성한 코드가 바로 이어지는 수많은 Promise에 의해 느려질 수 있다.
각 await은 이전의 작업이 끝날 때까지 기다린다.
=> 느려질 수 있다.
해결 방안 =>
// 빠른 비동기 작업으로 바꾸자
모든 Promise 오브젝트를 변수에 저장하여 미리 실행되게하고
변수가 사용 가능할 때 꺼내서 쓴다.
/*
시작 시간을 기록하고, timeTest() Promise가 fulfilled된 시간을 저장하여
두 시간의 차를 계산해 작업이 얼마나 걸렸는지 사용자에게 보여줍니다.
*/
// 느린 비동기 작업
function timeoutPromise(interval) {
return new Promise((resolve, reject) => {
setTimeout(function(){
resolve("done");
}, interval);
});
};
async function timeTest() {
await timeoutPromise(3000);
await timeoutPromise(3000);
await timeoutPromise(3000);
}
let startTime = Date.now();
timeTest().then(() => {
let finishTime = Date.now();
let timeTaken = finishTime - startTime;
alert("Time taken in milliseconds: " + timeTaken);
})
// 빠른 비동기 작업
function timeoutPromise(interval) {
return new Promise((resolve, reject) => {
setTimeout(function(){
resolve("done");
}, interval);
});
};
async function timeTest() {
const timeoutPromise1 = timeoutPromise(3000);
const timeoutPromise2 = timeoutPromise(3000);
const timeoutPromise3 = timeoutPromise(3000);
await timeoutPromise1;
await timeoutPromise2;
await timeoutPromise3;
}
let startTime = Date.now();
timeTest().then(() => {
let finishTime = Date.now();
let timeTaken = finishTime - startTime;
alert("Time taken in milliseconds: " + timeTaken);
})
[Javascript] 변수, 상수, 데이터 타입, 호이스팅, 스코프 체인 (0) | 2021.09.09 |
---|---|
[Javascript] 비동기 처리(4) : Loop 와 Async/Await (0) | 2021.08.18 |
[Javascript] 비동기 처리(2): Promise ⭐ (0) | 2021.08.17 |
[Javascript] Event Loop와 Call Stack ⭐ (0) | 2021.06.22 |
[React] Virtual-DOM, Reconciliation, fiber (0) | 2021.06.21 |