[javascript] 동기적 처리 및 sleep 구현

oznni·2021년 8월 29일
0

async, await 키워드 사용

동기적 처리 전

router.get('/', (req, res) => {
    ...
});

동기적 처리 후

// @brief : async함수로 리턴하는 랩핑함수
const wrapper = asyncFn => { return (async (req, res, next) => { try { return await asyncFn(req, res, next); } catch (error) { return next(error); } }); };

router.get('/', wrapper(async (req, res) => {
    ...
}));

비동기 함수 앞에 구현한 wrapper와 async 키워드를 붙여주면 된다.

sleep 구현

Promise 사용

//@param ms : setTimeout을 이용해서 밀리초 만큼 시간 지연
function sleep(ms) {
  return new Promise(resolve=>setTimeout(resolve, ms));
}

// @brief : async함수로 리턴하는 랩핑함수
const wrapper = asyncFn => { return (async (req, res, next) => { try { return await asyncFn(req, res, next); } catch (error) { return next(error); } }); };

router.get('/', wrapper(async (req, res) => {
    await sleep(2000); // 2초 지연
}));

async/await 키워드를 사용하면 마치 동기 프로그래밍 모델로 코딩을 하듯이 지연 함수를 호출할 수 있다.

적용 및 회고

수정 전 코드

FCM을 이용하여 node js 푸시 알람 구현하는 코드로, sleep 함수를 사용하고 싶었다.

 // @brief : FCM 데이터 페이로드
   const message = {
    data: {
      title: '상품일정알림',
      message: item_notification_type + ' 알림이 있습니다.',
      isScheduled : 'true',
      scheduledTime: item_notification_date
    },
    token: token
    };
    console.log(message);

    const sql = "INSERT INTO notification (user_id, item_id, item_notification_type, item_notification_date) VALUES(?,?,?,?)";
    const params = [user_id, item_id, item_notification_type, item_notification_date];

    // @brief : DB에 알림정보 저장
    db.get().query(sql, params, function(err, result){
        if(err) {
            console.log(err);
        } else {
              if (result.length === 0) {
                  console.log("Failed to inserted the notification for data.");
                  res.status(500).json({
                    success: false,
                    message: "서버 에러",
                  });
                } else {
                  console.log("Successfully inserted data into the notification!!");

                // @brief : DB에 알림이 성공적으로 추가된 경우 fcm 알림 전송
                 admin.messaging().send(message)
                    .then(function (response) {
                      console.log('[fcm] Successfully sent message: : ' + response)
                    })
                    .catch(function (err) {
                      console.log('[fcm] Error Sending message!!! : ' + err)
                    });

                  res.status(200).json({
                    success: true,
                    message: "알림 추가 성공",
                  });
                }
              }
         db.releaseConn();
    });
});

문제 상황

FCM을 이용하여 node js 푸시 알람 구현하던 도중 문제가 있었다.
db에 성공적으로 정보를 저장한 후 fcm 알림을 요청하는데, 이 부분의 로그가 출력되지 않는 것이다.

admin.messaging().send(message)
	.then(function (response) {
		console.log('[fcm] Successfully sent message: : ' + response)
	})
	.catch(function (err) {
		console.log('[fcm] Error Sending message!!! : ' + err)
	});

원인을 생각해보니 해당 코드를 실행 중에 db.get().query(sql, params, function(err, result)가 종료되어 로그가 출력이 되지않는 것 같았다. 그래서 sleep 함수를 써서 함수 종료를 지연시키면 해결할 수 있을 것이라고 생각했다. 근데 자바스크립트에서는 파이썬과 달리 sleep() 함수가 없었고, 구현해야했었다.

수정한 코드 (추후 수정 필요)

//@param ms : setTimeout을 이용해서 밀리초 만큼 시간 지연
function sleep(ms) {
  return new Promise(resolve=>setTimeout(resolve, ms));
}

// @brief : async함수로 리턴하는 랩핑함수
const wrapper = asyncFn => { return (async (req, res, next) => { try { return await asyncFn(req, res, next); } catch (error) { return next(error); } }); };

 // @brief : FCM 데이터 페이로드
   const message = {
    data: {
      title: '상품일정알림',
      message: item_notification_type + ' 알림이 있습니다.',
      isScheduled : 'true',
      scheduledTime: item_notification_date
    },
    token: token
    };
    console.log(message);

    const sql = "INSERT INTO notification (user_id, item_id, item_notification_type, item_notification_date) VALUES(?,?,?,?)";
    const params = [user_id, item_id, item_notification_type, item_notification_date];

    // @brief : DB에 알림정보 저장
    db.get().query(sql, params, wrapper(async(err, result)=>{
        if(err) {
            console.log(err);
        } else {
              if (result.length === 0) {
                  console.log("Failed to inserted the notification for data.");
                  res.status(500).json({
                    success: false,
                    message: "서버 에러",
                  });
                } else {
                  console.log("Successfully inserted data into the notification!!");

                // @brief : DB에 알림이 성공적으로 추가된 경우 fcm 알림 전송
                 admin.messaging().send(message)
                    .then(function (response) {
                      console.log('[fcm] Successfully sent message: : ' + response)
                    })
                    .catch(function (err) {
                      console.log('[fcm] Error Sending message!!! : ' + err)
                    });

                  res.status(200).json({
                    success: true,
                    message: "알림 추가 성공",
                  });
                }
              }
         db.releaseConn();
    }));
});

알림 수신 성공🥺

공부할 것

  • 비동기 처리
    - Callback
    - Promise
    - async/await

참고

async/await 적용하기
자바스크립트에서 sleep 구현하기

profile
Android Developer.

0개의 댓글