9-3 비동기, Promise, async & await

airbus·2025년 3월 19일

프로그래머스

목록 보기
40/93

9-3 비동기, Promise, async & await

비동기

동기 : 동시에 일어나는 것, 요청과 결과가 동시에 일어남. 순서에 따라 작업이 진행되므로, 여러가지 요청을 동시에 처리하지 않음(느린처리).
비동기 : 흐름의 순서와 관계없이(이벤트가 완료될 때까지 기다리지않고) 작업이 처리되어, 요청과 결과가 동시에 일어나지 않음(빠른처리).


저번에 작성한 주문api 코드에서, delivery_id 와 order_id를 받기위해 변수만 선언하면
값이 undefined되어서 null이라고 에러가 발생합니다.

// 주문하기

const order = (req, res) => {
    const { items, delivery, totalQuantity, totalPrice, userId, firstBookTitle } = req.body;

    let delivery_id;
    let order_id;

    let sql = "INSERT INTO delivery (address, receiver, contact) VALUES (?, ?, ?)";
    let values = [delivery.address, delivery.receiver, delivery.contact];


    conn.query(sql, values,
        (err, results) => {
            if (err) {
                console.log(err);
                return res.status(StatusCodes.BAD_REQUEST).end();
            }
            delivery_id = results.insertId;

            console.log("result id", results.insertId);
            console.log("conn query", delivery_id);

        })
    

        console.log("out", delivery_id);
~
~

로그에 값을 출력해보면 "conn query"에서의 delivery_id는 값이 들어가있지만 아래 "out"의 delivery_id는 undefined 입니다.
(order_id 도 마찬가지)

Node의 특징인 non blocking, 비동기 방식으로 동작하기에 값이 들어가기 이전에 호출이 되어서 발생하는 문제입니다.
이전에 실행되는 코드들을 기다린 다음 실행될 수 있도록 해주어야 합니다.

  • 비동기가 필요가 없을 때
  • 이전 코드들의 시간을 다 기다려주고, 순서에 맞춰서 코드를 실행합니다.

방법

  • 콜백함수
  • promise( resolve, reject )
  • then & catch
  • async & await (ES2017 Promise)

Promise

Promise() 객체

  • new Promise()로 객체를 생성
  • 콜백함수의 매개변수로 resolve, reject를 받습니다.
  • executor 성공 시 resolve가 실행됩니다.
  • executor 실패 시 reject가 실행됩니다.

Promise 객체는 작업 완료시 resolve or reject 둘 중 하나는 무조건 실행한다고 약속


let pro = new Promise(function(resolve, reject) {

    setTimeout(() => resolve("완료"), 2000);

}) 

Promise.then

  • promise의 기본 메서드
  • promise의 작업이 완료되면 실행됩니다. (성공 시 1번 매개변수가, 실패 시 2번 매개변수가 실행됩니다.)
pro.then(function(result){console.log(result)}, function(err){});
=> 2초뒤 완료 log출력됨

Promise chaining

  • then. + then. + ...
  • 비동기 처리를 순차적으로 여러개 실행 / promise를 연속으로 실행
let pr = new Promise(function(reslove, reject) {
    setTimeout(() => reslove("완료"), 2000);
}).then(
    function(result) {
        console.log(result);
        return result + "!";
    },
    function(error){}
).then(
    function(result) {
        console.log(result);
        return result + " !!";
    },
).then(
    function(result) {
        console.log(result);
        return result + " !!!"
    }
)
=>
완료 (성공)
완료! (성공)
완료! !! (성공)
완료! !! !!! (성공)

async & await

  • promise 객체를 좀 더 쉽게 사용하는 방법 = 쉬운 비동기 처리방식
  • async는 무조건 Promise 객체를 반환합니다.
  • 반환값이 Promise가 아니라면 Promise.resolve()로 감싸줍니다.
  • await은 async함수내에서 사용되어야 합니다. (async 함수 안에서만 동작) = Promise가 처리될 때까지 대기 후 await 실행
    = promise 객체가 일이 끝날 때까지 기다릴 수 있는 공간을 제공
async function f() {
    // 1
    // promise 객체 한개당 => query  하나
    let promise1 = new Promise(function (resolve, reject) {
        setTimeout(() => resolve("완료1"), 2000);
    });

    let result1 = await promise1; // Promise 객체가 일 다 할때까지 기다려줌
    console.log(result1);


    // 2
    let promise2 = new Promise(function (resolve, reject) {
        setTimeout(() => resolve("완료2 with " + result1), 2000);
    });

    let result2 = await promise2
    console.log(result2);

    // 3
    let promise3 = new Promise(function (resolve, reject) {
        setTimeout(() => resolve("완료3 with " + result2), 2000);
    });

    let result3 = await promise3;
    console.log(result3);
    
}


f();

=>
완료1
완료2 with 완료1
완료3 with 완료2 with 완료1

그러면 위와같이 async await이나 promise를 사용하기만 하면 해결이 되나? 9-4


기타 보충:
async await 을 보면 순차적으로 실행할 수 있으니까 무조건 동기적으로 처리되는구나 할 수 있는데 사실 그렇게 보이는 것일 뿐.
비동기적으로 처리되고 있는 중.

저번에 Node특징 정리할 때 알아본 동작방식 중

Nodejs는 싱글 스레드 이지만, 싱글 스레드라고 한 이유는 개발자가 컨트롤 가능한 스레드가 한 개 이기 때문에 싱글스레드로 동작한다고 한 것, 실제로는 여러개의 스레드로 처리가 되는 것.

라고 하였는데, async 하는 스레드만 해당 함수내에서 기다리는 것이고, 메인 스레드에서는 계속해서 다른 작업이 처리됩니다.

0개의 댓글