How to replace short (less than a minute) setTimeouts in Event Page Extensions

若如初见. 提交于 2020-01-13 09:16:10

问题


The documentation about transitioning from background persistent extensions to non persistent Event Pages, states:

If your extension uses window.setTimeout() or window.setInterval(), switch to using the alarms API instead. DOM-based timers won't be honored if the event page shuts down.

Fair enough, but the alarms API documentation states:

when can be set to less than 1 minute after "now" without warning but won't actually cause the alarm to fire for at least 1 minute.

So, i have a short setTimeout in my EventPage, it takes 5s, how can i ensure it completes, if i can't use an alarm for those short times. Setting a 1 minute long alarm is not a solution for me.


回答1:


If you need to do something like this often, then wOxxOm is absolutely correct: Event page is a bad approach for your needs.

Documentation should not be misinterpreted: persistent background pages are not in any way deprecated. Event pages are a more efficient solution for background pages that process things irregularly and/or rarely.

Frequent timers do not fall into this category. After all, "spinning up" the Event page frequently is a considerable resource/performance loss as opposed to keeping it ready at all times.


Now, the question becomes more tricky when you only need to do this timeout as a part of infrequent, as opposed to regular, action, when you think that long pauses between those actions can benefit from Event page model. This can happen!

The goal then becomes to appear "busy" enough to Chrome so that the Event page shutdown does not happen.

Probably the easiest way is to just invoke the timer a bit more frequently, as the Event page is guaranteed to persist for a couple of seconds:

var SAFE_DELAY = 1000; // Guaranteed not to fall asleep in this interval

function setBusyTimeout(callback, delay) {
  if(delay <= SAFE_DELAY) {
    setTimeout(callback, delay);
  } else {
    var start = Date.now(); // setTimeout drifts, this prevents accumulation
    setTimeout(
      function() {
        setBusyTimeout(callback, delay - (Date.now() - start));
      }, SAFE_DELAY
    );
  }
  // Can be expanded to be cancellable by maintaining a mapping
  //   of "busy timeout IDs" to real timeoutIds
}

It's a sort of a very "sparse" busy-wait, that should not consume much resources - again, if used infrequently.

Other soultions may include maintaining an open port through chrome.runtime.connect and friends. I doubt it's more CPU-efficient than the above.



来源:https://stackoverflow.com/questions/34271673/how-to-replace-short-less-than-a-minute-settimeouts-in-event-page-extensions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!