타이머(timer)든 알람(alarm)이든 작성시 정말 중요한 사항

2022. 11. 14. 14:49크롬 익스텐션

타이머든 알람이든 동작은 거의 같다. 세세한 차이는 있겠지만 front에서는 setTimeout을 사용하고 back에서는 alarm을 사용해야 오류없이 작성이 가능하다.

타이머든 알람이든 사용할때 가장 중요한 사항이 하나 있는데 [호출 -> 끄기 -> 완료확인 -> 다시 켜기] 과정을 반드시 지켜줘야 내가 원하는 방식으로 사용이 가능하다.

타이머 자체를 끄지않고 호출해놓으면 내가 원하는 작업이 끝나기도 전에 다시 타이머가 발생해서 프로젝트를 완전히 엉망으로 만드는 수가 있다.

이는 클라이언트용 앱을 제작할때도 중요하지만, 크롬 익스텐션처럼 웹작업을 할때는 더더욱 중요하다. 웹은 언제든 끊길 위험도 있고, 예상과 다르게 속도가 오래 걸릴수도 있기 때문이다.

특히나, background에서 alarm을 사용할때는 더더욱 신경을 써줘야 한다.

1. front에서 sendMessge를 이용해서 back의 alarm을 켠다.
  - 무조건 알람을 켜주면 진짜 별 희한한 상황에서 알람이 발생하니 반드시 내가 원하는 페이지나 프레임등의 로딩완료 확인후 직접 알람을 켜줘야 한다.

2. bakc의 alarm 발생시 반드시 해당 alarm을 먼저 끈 뒤에 원하는 작업을 수행하자.
  - 이게 가장 핵심중 핵심이다. alarm이 발생하면 무조건 끄자.

3. 원하는 작업 수행 완료후 back에서 front로 sendMessage를 이용해서 작업완료를 알린다.

4. front에서 작업완료 확인후 다시 위 1번 과정을 통해 alarm을 켠다.

alarm은 한번 켜고 계속 놔두는게 아니라 - 물론 진짜 알람으로 매시간 한번씩 동작하는등의 작업은 그냥 켜놓고 써도 되겠지만 - front에서 켜주고, back에서 alarm이 발생하는 순간 끄고, 작업 완료까지 확인후 다시 front에서 켜주도록 해줘야 거짓말 조금 보태서 365일 24시간 쉬지않고 돌아가는 프로그램 작성이 가능하다.

위 과정을 코드로 표현해보면 아래와 같다.

 

// 1. front에서 alarm을 켜준다. - 10초후 알람 발생하도록 설정
chrome.runtime.sendMessage({action: "start_alarm", sec: 10});

// 2. back에서 message를 받으면 alarm을 켠다.
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
  if (request.action === 'start_alarm')
    chrome.alarms.create('alarm_my', {periodInMinutes: request.sec / 60});
};

// 3. back에서 alarm 리스너를 생성해서 지정된 시간후 알람 실행
chrome.alarms.onAlarm.addListener(function (alarm) {   // 알람 처리
  if (alarm.name == 'alarm_my') {
    console.log('alarm_my Fired!');
    chrome.alarms.clear('alarm_my');  // 여기여기 - 반드시 알람을 꺼주자. 별표 다섯개
    SomeFunction();
  }
});

// 4. 작업 완료후 front에 완료상황 알림
function SomeFunction()
{
  ...
  var data = '작업완료후 front에 전달할 값';
  chrome.tabs.sendMessage(TargetTab.id, { action: 'job_complete', result: data });
};

// 5. front에서 작업완료 확인
chrome.runtime.onMessage.addListener(function (request, sender) {
  if (request.action === "job_complete")  { SomeFunction(request.result); }
});

// 6. front에서 다시 알람 켜기
function SomeFunction(data) {
  ...
  chrome.runtime.sendMessage({action: "start_alarm", sec: 10});
};

혹시 초보자라 하더라도 위 소스를 몇번 곱씹다보면 원하는 답을 내릴 수 있을것이다.

 

위에 TargetTab.id라는 값이 나오는데 이에 관련해서도 중요한 사항이 있으니 다음번에 좀더 자세히 알아보자. back이 메시지를 보내야 하는 대상 front를 지칭한다고 대략적으로 생각하면 될듯 하다.

 

끝.

 

ps. alarm을 사용하려면 manifest.json의 permissions에 "alarms"를 추가해서 권한을 획득해야 한다.

반응형