[node.js] 비동기처리를 위한 Javascript의 함수/기능들

Hyo Kyun Lee·2021년 7월 28일
0

node.js

목록 보기
20/34

1-1. callback

함수의 인자를 전달받을 때 변수가 아닌, 함수를 전달받는 경우를 말한다.

function Reference(id, log){
  const user = {
    id : id,
    name : "User No_" + id
  }
  //log 함수를 인자로 받아 활용하는 logic
  log(user)
}

//log인자에 전달되는 함수를 callback, 이 callback함수를 할당받는다.

Reference(1, (user) => {
  console.log("user info : ", user);
})

이처럼 callback 처리를 이용할 경우, return값을 반환받아 다시 변수로 할당하는 번거로운 작업을 하지 않아도 된다.

즉 함수로 인자를 바로 전달하여, return없이 즉시적인 반환이 가능하다.

비동기처리 관점에서 보았을때 callback은 return을 받기까지의 logic을 기다리는 과정을 없앨 수 있고, 이를 통해 undefined 이슈를 방지할 수 있다.

function Reference(id) {
  let user;
  setTimeout( () => {
    console.log("after 100ms");
    user = {
      id : id,
      name : "User No_" + id
    };
  }, 100);
  return user; 
}

Reference(1) //undefined

위 코드에서 일반적인 return 문을 통한 logic으로 함수를 실행한다면, user는 undefined 상황에서 return되어 이슈가 발생한다.

function Reference(id, (log)=>{
  let user;
  setTimeout( () => {
    console.log("after 100ms");
    user = {
      id : id,
      name : "User No_" + id
    };
   log(user);
  }, 100); 
}

Reference(1, (user) =>{
  console.log("user info: ", user)
})

이처럼 위 return 을 통한 일반적인 함수형태를 callback 형태로 전달하여, 내부적으로 비동기처리 logic 흐름을 유지한 상황에서 callback 함수를 호출하면 비동기처리를 정상적으로 처리할 수 있다.

1-2. Callback의 promisify

Promise의 resolve 구문을 간결히 나타내는 함수형 구문

promisify는 util module에 내장되어있는 기능이다.

일반적으로 node.js 환경에서 비동기처리를 구현할 때 가장 많이 사용하는 logic은 async - await 구문이며, 이때 Promise 함수를 같이 사용하면서 비동기처리가 성공했을때 resolve 문으로 구현하는 형식으로 처리한다.

//Pseudo code
async() => {
  const res = await new Promise((resolve, reject) => {
    pro(err, val) => {
      if(err) {
        console.error(err)
      }else{
        resolve(val)
      }
    }
  })

이 promise 구문을 promisify를 이용하면 resolve 구문을 훨씬 간결하게 나타낼 수 있다.

다만 err 처리는 별도 then이나 err를 통해 구현해야한다.

const proPromise = util.promisify(pro) // 위 Promise 객체에 사용되는 pro함수 자체를 promisify 인자로 전달.

//promise resolve 구문을 res로 반환받는다
const res = await proPromise()

//promise resolve 구문후, err logic에 대해선 별도 작성 필요
const res = await proPromise().then(logic)

2-1. Promise / resolve - reject

Promise의 핵심은 비동기 처리 결과(resolve, reject)를 객체화하여 반환한다는 점이다.

비동기처리 관점에서 Promise는 별도의 분기처리없이 곧바로 resolve를 통해 logic 구현이 가능하다는 점, Promise logic 실행(resolve)후 then을 통해 이후 logic이나 error 처리를 할 수 있다는 점이 중요하다.

2-2. async - await

callback / Promise의 loop hell 문제를 보완하고자 async await 기능이 추가되었다.

async - await 구문에 promise 객체를 활용하여 비동기처리를 구현할 수 있고, promise 객체 자체가 비동기처리에 적합한 logic이기 때문에 많이 활용하는 것이다.

await 구문을 사용하기 위해선 반드시 async 함수 안에서 사용해야 한다.

async () => await timeInterval({
  const value = true
  const res = new Promise((resolve, reject) => {
    if(value){//Promise 객체호출후, logic 성공시 resolve를 통해 true
      resolve({
        console.log("true") 
    })}else{//Promise 객체호출후, logic 실패시 reject를 통해 false
      reject({
        console.log("false")
    })
  }
}), 1000)

console.log(value)
try{
	const value = await res
    console.log(value)
}catch(err){
  console.error(err)
}

Promise와 async - await 구문이 조합되어있는 logic이다.

여기서 중요한 점은

  • async 함수 내 await 구문을 사용하여 console.log는 timerInterval 내 logic이 완전히 종료될 때까지 대기한다.
  • 비동기처리에서 event loop 발생시점 및 logic 흐름을 위와 같이 async - await 구문을 통해 control할 수 있다.
  • 다만 async - await 구문은 단순히 logic 흐름을 조절하는 구문으로, error 처리를 위해선 try - catch 구문 내에서 활용하여, error logic을 별도 구현할 수 있다.

Promise / async - await는 모두 비동기 처리와 관련되어 있으나, logic 구현이나 특징 등에서 다소 차이가 있기 때문에 세부적인 부분들을 정확히 인지하고 활용하도록 하자.

3. 참조링크

비동기 - callback
https://www.daleseo.com/js-async-callback/
https://www.hanumoka.net/2018/10/24/javascript-20181024-javascript-callback/

promisify
https://techbless.github.io/2020/02/13/Node-js-Callback%EC%9D%84-Promise%EB%A1%9C-Promisify-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0/
https://medium.com/harrythegreat/node-promisify%EB%A1%9C-promise-%EC%89%BD%EA%B2%8C-%EB%A7%8C%EB%93%A4%EA%B2%8C-27e58a211cf2

Promise resolve - reject
https://velog.io/@cyranocoding/2019-08-02-1808-%EC%9E%91%EC%84%B1%EB%90%A8-5hjytwqpqj
https://velog.io/@delilah/Node.js-%EB%B9%84%EB%8F%99%EA%B8%B0-Promise-%EB%8F%99%EC%9E%91%EC%9B%90%EB%A6%AC

async - await
https://velog.io/@pilyeooong/Promise%EC%99%80-asyncawait-%EC%B0%A8%EC%9D%B4%EC%A0%90

0개의 댓글