JS. 비동기 함수

MJ·2023년 6월 12일
0
post-thumbnail

비동기 함수

  • 비동기 코드의 가독성을 올려주는 함수.

  • Promise 객체 위에 적용된다.

  • asyncawait 함수가 존재 합니다.


1.1 asnyc 함수

  • 함수를 비동기 함수로 선언하는 키워드

  • 함수 앞에 async 키워드를 사용하면 return 하지 않아도 Promise 객체가 반환된다.

/* 일반 함수 */
function hello(){
  
}

console.log(hello());	// undefined
/* async 키워드로 비동기 함수 선언 */
async function hello(){
// return new Promise() 를 사용하지 않아도 됨

}

console.log(hello());	// Promise { undefined }

1.2 async 성공 / 실패

  • 비동기 함수 내부에 반환 값이 있으면 resolv를 반환하고, 값이 없거나 오류를 전달하면
    reject를 반환합니다.

  • Throw 문을 사용해서 reject에 전달될 에러 구문을 정의할 수 있다.

/* resolv */

const sing = async () => {
    return 'asds';
}

sing().then((data) => {
    console.log(data);	// asds 
})
/* reject */

const sing = async () => {
    throw 'Error!';
    return 'asds';	// throw 구문으로 인해 return이 무시된다
}

sing()
    .then((data) => {
        console.log(data);
    })
    .catch((data) => {
        console.log(data)	// Error! 
    })
/* reject - 2 */

const sing = async () => {
    throw new Error('Error!');	// error 객체를 throw 구문에 전달
    return 'asds';	// 무시됨
}

sing()
    .then((data) => {
        console.log(data);
    })

Error 객체를 throw 구문에 전달하게 되면 오류난 부분과 오류를 해결한 부분을 확인 가능



await

  • 비동기코드를 동기적으로 보이게 해주는 키워드.

  • Promise가 값을 반환할 때 까지 기다리기 위해서 비동기 함수의 실행을 일시정지합니다.
    비동기 함수에서만 적용되기에 async와 한 쌍으로 사용 된다.

  • await를 사용하면 .then 메서드나 함수에 return을 사용할 필요가 없어진다.


2.1 resolv 상태에서 await 사용

/* 배경색상을 변경하는 Promise */

const delayChangeColor = function (color, delay) {
    return new Promise((resolv, reject) => {
        setTimeout(() => {
            document.body.style.backgroundColor = color;
            resolv();
        }, delay)
    })
}

/* 비동기 함수 사용 */
async function color() {
    await delayChangeColor('red', 1000);
    await delayChangeColor('green', 1000);
}

async function colorFinish() {
    await color();
    console.log('작업 완료');
}

colorFinish();

/* 
동작 원리

1. colorFinish(); 함수 호출
2. 함수 내부에서 color() 함수를 호출합니다. 함수는 async 키워드로 비동기함수가 되었으며 비동기함수에서는
await 키워드를 사용해서 현재 프로미스가 완료될 때 까지, 다음 프로미스를 대기하게 만드는 역할을 수행

3. 빨간색으로 색상을 변경하는 함수의 프로미스가 완료되면, 초록색으로 변경하는 함수가 호출 됩니다.
4. 이 구문은 .then 메서드 내부에 return 함수와 동일하게 작동하며 가독성은 더욱 뛰어납니다.
5. color() 함수의 역할이 종료되면, colorFinish() 함수로 돌아와서 console.log를 출력합니다.
*/

Promise 작업이 완료되면 마지막으로 콘솔이 출력된다.


2.2 reject 상태에서 await 사용

const fakeRequest = (url) => {
    return new Promise((resolv, reject) => {
        const delay = Math.floor(Math.random() * 4500) + 500;

        setTimeout(() => {
            if (delay > 4000) {
                reject('연결 실패');
            } else {
                resolv(`${url} 주소로 연결 성공`);
            }
        }, delay)
    })
}

async function makeTwoRequest() {
    let data1 = await fakeRequest('page/1');
    console.log(data1);
    let data2 = await fakeRequest('page/2');
    console.log(data2);

    console.log('reject가 되면 안보인다.')
}

makeTwoRequest()

/* 
makeTwoRequest() 함수는 fakeRequest() 함수로 부터 요청을 전달합니다.
프로미스의 결과값을 data1~2 변수에 저장하고, 작업이 완료되면 console.log를 출력합니다.

마지막 콘솔로그의 출력은 프로미스값이 resolv 인 경우에만 해당되고, reject 인 경우라면
오류 발생으로 인해 출력되지 않게 됩니다.

이를 해결하기 위해서 try.. catch 구문이 필요합니다.
*/

resolv() 인 경우에만 마지막 콘솔로그가 출력 된다.


/* try..catch 구문으로 reject 인 경우 에러 핸들링하기 */

const fakeRequest = (url) => {
    return new Promise((resolv, reject) => {
        const delay = Math.floor(Math.random() * 4500) + 500;

        setTimeout(() => {
            if (delay > 4000) {
                reject('연결 실패');
            } else {
                resolv(`${url} 주소로 연결 성공`);
            }
        }, delay)
    })
}

async function makeTwoRequest() {
    try {
        let data1 = await fakeRequest('page/1');
        console.log(data1);
      
        let data2 = await fakeRequest('page/2');
        console.log(data2);
    } catch (e) {
        console.log(e);
    }
    console.log('reject가 되어도 보입니다.')
}

makeTwoRequest()

/* 
프로미스의 결과 값이 reject가 되면 catch 구문으로 전달되어서 오류를 전달하고, 다음 코드가 실행되는데에
오류가 영향을 주지 않습니다.
*/

reject인 경우에도 에러 핸들링으로 인해서 마지막 console.log도 출력됩니다.

profile
프론트엔드 개발자가 되기 위한 학습 과정을 정리하는 블로그

0개의 댓글