JavaScript - 비동기

holim0·2020년 12월 8일
6

오늘은 자바스크립트의 비동기 처리에 대해서 알아보겠습니다.

simple example

const second = () => {
                setTimeout(() => {
                    console.log("async");
                }, 2000);     // 2초 뒤 함수 실행.
            };

            const first = () => {
                console.log("hello");
                second();
                console.log("end");
            };

            first();

Result


➡️ hello -> end -> async 순으로 출력되는 것을 확인할 수 있다. (즉 2초동안 second 함수를 기다리지 않는다는 것을 확인.)

  • setTimeout() function 은 js 외부 web apis 에서 온다. ex) DOM events , XMLHttpRequest(), setTimeout() etc.



Callback 지옥

➡️ 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

  • Object that keeps track about whether a certain event has happened already or not.
  • Determines what happens after the event has happened.
  • Implements the concept of a future value that we are expecting.



[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!");
                });
  • 함수가 아무 문제가 없다면 resolve 를 통해서 promise value를 return 한다.
  • 그 후 then 을 통해서 그 값을 받을 수 있다. 오류가 나면 catch 로 처리할 수 있다.
  • then은 chaining 할 수 있다. (위의 코드 참고)



Async/Await


  • awaitasync 안에서만 사용할 수 있다.

 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}`);
            });            //



AJAX & APIS


  • AJAX (Asynchronous Javascript And Xml)
  • APIS (Application Programming Interface)



fetch

➡️ 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 로 에러 핸들링을 할 수 있다.

profile
매일 조금씩 성장하고 있는 개발자입니다.

0개의 댓글