콜백 / Promise async-await

Jiwon Youn·2020년 12월 31일
0

비동기 처리?

자바스크립트의 비동기 처리란 특정 로직의 실행이 끝날 때까지 기다려주지 않고 나머지 코드를 먼저 실행

비동기 처리 예

// setTimeout 으로 인한 비동기(비순차적)
function asyncFunction1() {
    setTimeout(function() {
        console.log(1)
    }, 1000)
}

function syncFunction1() {
    console.log(2)
}

function syncFunction2() {
    console.log(3)
}

asyncFunction1()
syncFunction1()
syncFunction2()

// 2 3 1 출력

setTimeout 함수로 인해 실행 순서와 다르게 비동기적

콜백 함수

위의 코드를 순차적으로 1 2 3 출력하게 하려면?

function asyncFunction1(cb) {
    setTimeout(function() {
        console.log(1)
        cb()
    }, 1000)
}

function syncFunction1(cb) {
    console.log(2)
    cb()
}

function syncFunction2(cb) {
    console.log(3)
}

asyncFunction1(function(asyncFunction1Result) {
    syncFunction1(function(syncfunction1Result) {
        syncFunction2()
    })
})
// 1 2 3 
  • 콜백 함수를 이용해 비동기적 작업 이후에 콜백 함수를 실행
  • 비동기 함수가 return 하는 값이 있다면, 콜백함수의 파라미터로 전달
  • 단, 비동기적인 작업이 길어질수록 콜백이 깊어지고 콜백 내 if문 분기와 에러 핸들링이 어려움

Promise

콜백의 단점을 해결하기 위해 Promise 패턴 사용
비동기 작업을 콜백이 아닌 then으로 연결하고, catch로 에러를 편리하게 핸들링

function asyncFunction1() {
    return new Promise(function (resolve) {
        setTimeout(function() {
            console.log(1)
            resolve()
        }, 300)
    })
}

function asyncFunction2() {
    return new Promise(function (resolve) {
        setTimeout(function() {
            console.log(2)
            resolve()
        }, 100)
    })
}

function asyncFunction3() {
    return new Promise(function (resolve) {
        setTimeout(function() {
            console.log(3)
            resolve()
        }, 100)
    })
}

asyncFunction1()
asyncFunction2()
asyncFunction3()
// 2 3 1 을 출력하는 비동기 코드

Promise 패턴을 사용하기 위해서 return new Proimse()로 Promise 객체를 반환

asyncFunction1()
.then(function(result) {
    return asyncFunction2()
})
.then(function(result) {
    return asyncFunction3()
})
.catch(function(error) {
    console.log(error); 
    // Promise 체이닝 과정 중 에러가 발생하면 catch 블록 실행
})

// 1 2 3 출력
  • then을 이용해서 콜백을 대체
  • 콜백과 마찬가지로 then 함수의 파라미터로 결과값을 전달 가능
  • 단 Promise 패턴도 then이 깊어질 수 있고, if문 분기와 특정 에러 핸들링이 어렵다는 단점 존재

async await

이러한 문제들을 해결하기 위해 async await 을 사용

async function async1() {
    return 1
}

console.log(async1() instanceof Promise) 
// async 함수는 항상 Promise 객체를 반환
const asyncReturn = async1();
asyncReturn.then(); // 따라서 async 함수의 리턴값에도 then 함수가 있음

async 함수 내부에서 await을 사용 가능

function asyncFunction1() {
    return new Promise(function (resolve) {
        setTimeout(function() {
            resolve(111)
        }, 300)
    })
}

async function async1() {
    const result = await asyncFunction1() 
    // await 키워드로 다른 promise를 반환하는 함수의 실행 결과값을 변수에 저장
    console.log(result) // 111
}

async function async2() {
    let result
    try {
        result = await asyncFunction1() 
        // await에서 발생한 에러는 모두 아래 catch 블록에 걸림
    } catch(error) {
        console.log(error);
    }
    if(result === 'AAA') { // if문 분기도 일반 동기함수처럼 작성 가능
        doSomething()
    }
    return result;
}
  • async 함수 내부에선 await을 사용해 동기적 코드처럼 작성 가능
  • 주의점 : async 함수의 반환값은 항상 Promise 객체

0개의 댓글