오늘은 자바스크립트의 비동기 처리에 대해서 알아보겠습니다.
const second = () => {
setTimeout(() => {
console.log("async");
}, 2000); // 2초 뒤 함수 실행.
};
const first = () => {
console.log("hello");
second();
console.log("end");
};
first();
➡️ hello -> end -> async 순으로 출력되는 것을 확인할 수 있다. (즉 2초동안 second 함수를 기다리지 않는다는 것을 확인.)
setTimeout()
function 은 js 외부 web apis 에서 온다. ex) DOM events , XMLHttpRequest(), setTimeout() etc.
➡️ setTimeout 이 중첩되어서 물려있다. (안 좋음)
function getRecipe() {
setTimeout(() => {
const recipeID = [123, 532, 324, 2445];
console.log(recipeID); /// 서버에서 1.5초 후 가지고 오는걸 시뮬레이션
setTimeout(
(id) => {
const recipe = {
title: "pasta",
publisher: "heeje",
};
console.log(`${id} : ${recipe.title}`);
setTimeout(
(publisher) => {
const recipe = {
title: "pizza",
publisher: "heeje",
};
console.log(recipe);
},
1500,
recipe.publisher
);
}, 1000, recipeID[2]); // 3번째 parameter에 인자를 전달해준다.
}, 1500);
}
getRecipe(); // 함수 호출
[Promise States]
Callback 지옥 to Promise
const getIDs = new Promise((resolve, reject) => {
// resolve, reject 2개의 인자를 가진다.
setTimeout(() => {
resolve([123, 532, 324, 2445]); /// 성공하면 배열을 리턴한다.
}, 1500);
});
const getRecipe = (recID) => {
return new Promise((resolve, reject) => {
setTimeout(
(ID) => {
const recipe = {
title: "pasta",
publisher: "heeje",
};
resolve(recipe);
},
1500,
recID
);
});
};
const getLelated = (publisher) => {
return new Promise((resolve, reject) => {
setTimeout(
(publisher) => {
const recipe = {
title: "pizza",
publisher: "heeje",
};
resolve(recipe);
},
1500,
publisher
);
});
};
getIDs
.then((IDs) => {
// IDs 에 배열이 전달된다.
console.log(IDs);
return getRecipe(IDs[2]); // 다음 then 에 전달 해줄 수 있다.
})
.then((recipe) => {
// .then 을 써서 chaining 이 가능하다.
console.log(recipe);
return getLelated(recipe.publisher);
})
.then((recipe) => {
console.log(recipe);
})
.catch((error) => {
// reject 됐을 때
console.log("Error!");
});
await
은 async
안에서만 사용할 수 있다. getIDs
.then((IDs) => {
// IDs 에 배열이 전달된다.
console.log(IDs);
return getRecipe(IDs[2]); // 다음 then 에 전달 해줄 수 있다.
})
.then((recipe) => {
// .then 을 써서 chaining 이 가능하다.
console.log(recipe);
return getLelated(recipe.publisher);
})
.then((recipe) => {
console.log(recipe);
})
.catch((error) => {
// reject 됐을 때
console.log("Error!");
});
⬇️ async 와 await 방식으로 변경 ⬇️
async function getRecipesAw() { // async 함수 선언
const IDs = await getIDs; // getIDs 에서 충족되면 들고 온다. (resolve 가 return 한 값)
console.log(IDs);
const recipe = await getRecipe(IDs[2]); // 마찬가지로 chaining 이 가능하다.
console.log(recipe);
const related = await getLelated(recipe.publisher);
console.log(related);
return recipe; //Promise return
}
const rec = getRecipesAw(); // promise return 값을 받는다.
console.log(rec); // 함수가 백그라운드에서 실행되고 있고 아직 return 값이 없기 때문에 아무런 값이 뜨지 않는다.
// 대신 이렇게 //
getRecipesAw().then((result) => { // getRecipesAw는 promise를 리턴하기 때문에 then 을 통해서 리턴값을 받을 수 있다.
console.log(`hihi ${result}`);
}); //
➡️ fetch
를 통해서 오픈 api를 들고 올 수 있다.
function getID(name) {
fetch(`https://api.github.com/users/${name}`) // url를 넣는다.
.then((result) => {
console.log(result);
return result.json();
})
.then((data) => {
console.log(data);
const log = data.id;
console.log(log);
})
.catch((error) => { // error handler
console.log(error);
});
}
getID("iliakan");
getID("remy");
⬇️ async 와 await 방식으로 변경 ⬇️
async function getIDaw(name) { // async 함수 선언.
try {
const result = await fetch(
`https://api.github.com/users/${name}`
);
const data = await result.json();
console.log(data);
console.log(data.id);
} catch (error) {
console.log(error);
}
}
getIDaw("iliakan");
getIDaw("remy");
:arrow_right: try
catch
로 에러 핸들링을 할 수 있다.