[JS] 비동기 처리 방법: promise, async & await

J.A.Y·2024년 1월 30일
0

javaScript

목록 보기
7/21

⭐Promise

## 문법
const myFirstPromise = new Promise((resolve, reject) => {
  // do something asynchronous which eventually calls either:
  //
  //   resolve(someValue)        // fulfilled
  // or
  //   reject("failure reason")  // rejected
});

예시

promise 사용 전 (콜백 늪에 빠진 것을 볼 수 있습니다.)

function greeting(name, cb){
	setTimeout(function() {
      console.log(name);
      cb(name);
    }, 1000);
}
function runBack(cb){
	setTimeout(function() {
      console.log('back');
      cb('back');
    }, 1000);
}
function runMessage(name, cb){
	setTimeout(function() {
      cb('hell');
    }, 1000);
}

greeting('kim', function(name) {
  console.log(name + '반가워');
  runBack(function (message1) {
    console.log(message1 + '을 실행했구나');
    runMessage(function (message2) {
      console.log('여기는' + message2);
    });
  });
});

promise 사용 후

    const greeting = new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve("kim");
            }, 1000);
    });

    const runBack = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve("back");
        }, 1000);
    });

    const runMessage = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve("hell");
        }, 1000);
    });

    greeting
        .then((name) => {
            console.log(name);
            return name;
        })
        .then((name) => {
            console.log(`${name} 반가워`);
            return runBack;
        })
        .then((message1) => {
            console.log(message1);
            return message1;
        })
        .then((message2) => {
            console.log(`${message2}을 실행했구나`);
            return runMessage;
        })
        .then((message3) => {
            console.log(`여기는 ${message3}`);
        });

응용버전

  • 직접 이름 값을 html에서 가져오면 재밌을 것 같아서 강의 쉬는 시간동안 10분 짬내서 만들어봤습니다.
  • 이름이 문자가 아닐 경우엔 다시 입력하라는 경고가 뜨면서 실행이 중단되도록 했습니다.
  • Promise를 쓰면 오류가 났을 때 어디서, 어떻게, 무엇이 잘못됐는지 확인할 수 있어 나중에 오류 찾고 수정할 때 유용할 것 같습니다.
  • <input type="text" name="name" id="name" /><button type="submit" onclick="greet()">Submit</button>
    function greet() {
        const nameIs = document.getElementById("name").value;
        const greeting = new Promise((resolve, reject) => {
            if (/^[a-zA-Z\uAC00-\uD7AF]+$/u.test(nameIs)) {
                //^[a-zA-Z]+$는 문자(대문자 또는 소문자)만 포함된 문자열과 일치하는 정규식 패턴
                //한글 문자는 유니코드 범위 '0xAC00' ~ '0xD7AF'
                setTimeout(() => {
                    resolve(nameIs);
                }, 1000);
            } else {
                alert("이름을 정확하게 입력해주세요");
                reject("name is not a string"); //콘솔창에 오류 내용을 뜨게 하면, 나중에 오류 찾을 때 편리합니다.
            }
        });
    
        const runBack = new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve("back");
            }, 1000);
        });
    
        const runMessage = new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve("hell");
            }, 1000);
        });
    
        greeting
            .then((name) => {
                console.log(name);
                return name;
            })
            .then((name) => {
                console.log(`${name} 반가워`);
                return runBack;
            })
            .then((message1) => {
                console.log(message1);
                return message1;
            })
            .then((message2) => {
                console.log(`${message2}을 실행했구나`);
                return runMessage;
            })
            .then((message3) => {
                console.log(`여기는 ${message3}`);
            });
    }

    ⭐⭐Async & Await

    가장 최근에 나온 문법으로, 사실 비동기 처리는 대부분 얘네 둘을 사용한다고 합니다.

    await를 사용해서 함수를 호출하려면 promise를 반환하는 함수 앞에 붙여야 합니다. 만약
    promise를 반환하지 않는 일반 함수일 경우엔 적용되지 않고, 'await' has no effect on the type of this expression 라는 문법 에러가 발생할 것입니다.

    promise, async, await을 사용하면 비동기 처리를 훨씬 간편하게 할 수 있습니다.

    문법

        async function name([param[, param[, ... param]]]) {
            statements
        }

    name: 함수 이름
    param: 함수에게 전달되는 인자 이름
    statement: 함수 본문, await이 포함됩니다.
    👉 await 키워드는 async 함수에서만 유효! async 함수의 본문 외부에서 사용하면 SyntaxError 발생!

    예시

    const getName = () => {
        return new Promise((resolve, reject) => {
            console.log("kim 님 반가워요.");
            resolve();
        });
    };
    const getPlace = () => {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                console.log(`여기는 back 입니다.`);
                resolve();
            }, 2000);
        });
    };
    const getMessage = () => {
        return new Promise((resolve, reject) => {
            console.log("Welcome to JS");
            resolve();
        });
    };
    
    async function exec() {
        await getName();
        await getPlace();
        getMessage();
    }
    exec();

    응용 - async & await으로 수정

    async와 await으로 고치기 전과 고친 후 코드를 보면 확연하게 코드 길이가 전보다 짧아진 것을 볼 수 있습니다.

    function greet() {
        const nameIs = document.getElementById("name").value;
        const getName = () => {
            return new Promise((resolve, reject) => {
                if (/^[a-zA-Z\uAC00-\uD7AF]+$/u.test(nameIs)) {
                    setTimeout(() => {
                        console.log(`${nameIs} 님 반가워요.`);
                        resolve();
                    }, 1000);
                } else {
                    alert("이름을 정확하게 입력해주세요");
                    reject("name is not a string");
                }
            });
        };
        const getPlace = () => {
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    console.log(`여기는 back 입니다.`);
                    resolve();
                }, 2000);
            });
        };
        const getMessage = () => {
            return new Promise((resolve, reject) => {
                console.log("Welcome to JS");
                resolve();
            });
        };
    
        async function exec() {
            await getName();
            await getPlace();
            getMessage();
        }
        exec();
    }
    profile
    Done is better than perfect🏃‍♀️

    0개의 댓글