JavaScript Async-Await

Lipton·2021년 8월 9일
0

JavaScript

목록 보기
5/6


Promise 기반 비동기를 다루는 또 다른 방법 Async-Await

async function 함수이름(){}
const 함수이름 = async() => {}

async-await

Promise 객체를 리턴하는 함수를 await으로 호출하는 방법
await을 사용하는 경우, 항상 async 함수 안에서 사용되어야 한다.

// Promise 객체를 리턴하는 함수
function p(ms) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(ms);
        }, ms)
    })
}

// Promise 객체를 리턴하는 함수를 await으로 호출하는 방법
// await을 사용하는 경우, 항상 async 함수 안에서 사용되어야 한다.
(async function main() {
const ms = await p(1000);
console.log(`${ms} ms 후에 실행된다.`);
})();

1000 ms 후에 실행된다.

비동기 처리 코드가 아래로 흘러가게 할 수 있다는 것이 가장 큰 장점이다.


try-catch

Promise 객체가 rejected 된 경우의 처리를 위해 try catch를 이용한다.

// Promise 객체가 rejected 된 경우의 처리를 위해 try catch를 이용한다.
function p(ms) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            // resolve(ms);
            reject(new Error('reason'))
        }, ms)
    })
}

// Promise 객체를 리턴하는 함수를 await으로 호출하는 방법
// await을 사용하는 경우, 항상 async 함수 안에서 사용되어야 한다.
(async function main() {
    try {
        const ms = await p(1000);
    } catch (error) { // reject 됐을 때 
        console.log(error);
    }
})();
Error: reason
    at Timeout._onTimeout (d:\project\javascript\new\async-await.js:6:20)
    at listOnTimeout (internal/timers.js:557:17)
    at processTimers (internal/timers.js:500:7)

resolve 전파

async function 에서 return 되는 값은 Promise.resolve 함수로 감싸서 리턴된다.

function p(ms) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            // resolve(ms);
            reject(new Error('reason'))
        }, ms)
    })
}

async function asyncP() { // p(ms) 실행
    return 'Mark';
}

(async function main() {
    try {
        const name = await asyncP(); //asyncP() return 출력
        console.log(name);
    } catch (error) {
        console.log(error);
    }
})();

Mark

resolve함수가 없어도 reject가 실행이 안되고 asyncP() 때문에 resolve가 실행이 된다.


function p(ms) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(ms);
            // reject(new Error('reason'))
        }, ms)
    })
}

async function asyncP() {
    const ms = await p(1000); // function p(ms) 실행
    return 'Mark: ' + ms;
}

(async function main() {
    try {
        const name = await asyncP(); //asyncP() return 출력
        console.log(name);
    } catch (error) {
        console.log(error);
    }
})();

Mark: 1000

1초 뒤에 실행


error의 전파

function p(ms) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            // resolve(ms);
            reject(new Error('reason'))
        }, ms)
    })
}

async function asyncP() {
    const ms = await p(1000); //p(ms) 실행
    return 'Mark: ' + ms; 
}

(async function main() {
    try {
        const name = await asyncP(); // 에러 받아와서 실행
        console.log(name);
    } catch (error) {
        console.log(error);
    }
})();
Error: reason
    at Timeout._onTimeout (d:\project\javascript\new\async-await.js:5:20)
    at listOnTimeout (internal/timers.js:557:17)
    at processTimers (internal/timers.js:500:7)

finally

function p(ms) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            // resolve(ms);
            reject(new Error('reason'))
        }, ms)
    })
}

async function asyncP() {
    const ms = await p(1000);
    return 'Mark: ' + ms;
}

(async function main() {
    try {
        const name = await asyncP();
        console.log(name);
    } catch (error) {
        console.log(error);
    } finally {
        console.log('end');
    }
})();
Error: reason
    at Timeout._onTimeout (d:\project\javascript\new\async-await.js:5:20)
    at listOnTimeout (internal/timers.js:557:17)
    at processTimers (internal/timers.js:500:7)
end

function p(ms) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(ms);
            // reject(new Error('reason'))
        }, ms)
    })
}

async function asyncP() {
    const ms = await p(1000);
    return 'Mark: ' + ms;
}

(async function main() {
    try {
        const name = await asyncP();
        console.log(name);
    } catch (error) {
        console.log(error);
    } finally {
        console.log('end');
    }
})();

Mark: 1000
end


연속되는 Promise 처리와, 연속되는 async await 처리 비교

function p(ms) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(ms);
        }, ms)
    })
}

// Promise 계속 리턴헤서 체이닝 되는 모양
p(1000)
    .then(() => p(1000))
    .then(() => p(1000))
    .then(() => {
        console.log('3000 ms 후에 실행');
})

// async await 한줄 한줄 실행
(async function main() {
    await p(1000);
    await p(1000);
    await p(1000);
    console.log('3000 ms 후에 실행');
})();

위 코드를 실행할 때에는 Promise 형식 / async await 형식 둘 중 하나만 써야 함. 둘 다 쓰면 에러


async-await의 Promise.all

function p(ms) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(ms);
        }, ms)
    })
}

(async function main() {
    const results = await Promise.all([p(1000), p(2000), p(3000)]);
    console.log(results);
})();

[ 1000, 2000, 3000 ]

3초 뒤에 결과 나옴


async-await의 Promise.race

function p(ms) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(ms);
        }, ms)
    })
}

(async function main() {
    const result = await Promise.race([p(1000), p(2000), p(3000)]);
    console.log(result);
})();

1000

1초 뒤에 결과 나옴

profile
Web Frontend

0개의 댓글

관련 채용 정보