TIL # 122 : [JavaScript] 들숨에 비동기 날숨에 처리 (3) : async await ... Promise || async?

셀레스틴 허·2021년 4월 28일
0
post-thumbnail

async-await

기본 문법

async function 함수명() {
	await 비동기_처리_메서드_명(); // 비동기 처리 메서드가 꼭 프로미스 객체를 반환해야 await가 의도한대로 동작한다
}
function fetchItems() {
  return new Promise(function(resolve, reject){
    var items = [1,2,3]
    resolve(items)
  });
}

async function logItems() {
  var resultItems = await fetchItems();
  console.log(resultItems);
}

await를 사용하지 않았다면 데이터를 받아온 시점에 콘솔을 출력할 수 있게 콜백함수나 .then()을 사용했을 것이다.

promise && async-await 코드 비교

function fetchUser() {
  var url = 'https.//todo.com/users/1';
  return fetch(url).then(function(response){
    return response.json();
  });
}

function fetchTodo() {
  var url = 'https.//todo.com/todos/1';
  return fetch(url).then(function(response){
    return response.json();
  });
}

// async await ->  기존 비동기 처리 코드 방식으로 사고하지 않아도 됨
async function logTodoTitle() {
  var user = await fetchUser();
  if (user.id === 1){
    var todo = await fetchToDo();
    console.log(todo.title);
  }
}

예외 처리한 logTodoTitle()

try{}, catch{}를 활용해 블럭안에 넣기

// 일반
async function logTodoTitle() {
  var user = await fetchUser();
  if (user.id === 1){
    var todo = await fetchToDo();
    console.log(todo.title);
  }
}

// try, catch
async function logTodoTitle() {
  try {
    var user = await fetchUser();
    if (user.id === 1){
      var todo = await fetchToDo();
      console.log(todo.title);
    }
  } catch(error) {
    console.log(error);
  }
}

내가 프로젝트 때 쓴 async-await 코드

route: http://localhost:8000/programs/1
GET으로 프로그램 한개(url parameter)를 가져오려고 할 때

ProgramController.js

const findOneProgram = async (req, res, next) => {
    try {
        const { programId } = req.params

        const program = await ProgramService.getOneProgram({ id: programId }) // await 사용
        if (!program) {
            const error = new Error('INVALID_INPUT')
            error.statusCode = 400
            throw error
        }

        res.status(200).json({ program })
    } catch (err) {
        res.status(err.statusCode).json({ message: err.message })
    }
}

ProgramService.js (Prisma ORM)

const getOneProgram = (field) => {
    const [uniqueKey] = Object.keys(field)

    const isKeyId = uniqueKey === 'id'
    const value = isKeyId ? Number(field[uniqueKey]): field[uniqueKey]

    return prisma.programs.findUnique({
        where: {
            [uniqueKey] : value 
        }
    }) 
}
  1. ProgramController는 ProgramService에서 정상적으로 데이터(결과값)가 넘어올 때까지 대기 -> await의 block code 특성 활용 (그러나 이것이 단점으로 작용하기도 함)
  2. 데이터 넘어올 시 program 변수 생성!

Promise || async-await?

결론: 둘 다 써야함!

해당 링크에서 말하는 언제 Promise, async를 쓰는 법

  1. async function는 promise를 반환한다. promise를 반환하는 각 function은 async function으로 볼 수 있다
  2. await는 async function을 call할 때 사용되며 resolve, reject 되길 기다린다 => code blocking을 하고있다는 사실을 망각하지 않기
  3. await는 포함되어 있는 async function의 코드 execution을 block, 막는다
  4. 함수2가 함수1의 결과값을 참조한다면 async를 써라
  5. 함수1, 2 둘 다 동시에 수행할 수 있다면 다른 두개의 async function을 만들고 동시에 돌려라
  6. 모든 promise를 동시에 돌리고 싶으면 promise array를 만들고 Promise.all(promisesArray)를 써라
  7. 작은 async function을 만들어라. 하나의 큰 async function와 많은 await는 blocking code를 많이 유발하기 때문에 별로다. 더불어 작은 async function을 만들 때 어떤 async function을 동시에 돌릴 수 있는지 생각하기 되기 때문에 두배로 좋다!
  8. blocking code를 만들어야 한다면 async function을 써라. 비동기 처리면에서도 좋다

    Reference:
    캠판님 https://joshua1988.github.io/web-development/javascript/js-async-await/
    https://betterprogramming.pub/should-i-use-promises-or-async-await-126ab5c98789

profile
Software Developer / 고통은 필연, 괴로움은 선택

0개의 댓글