Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chrome extension setTimeout not working properly

My first post here =].

I'm building a chrome extension and I'm using a setTimeout recursively. I noticed that if I set it to up to 13secs, it works, but if I set it to 14secs+ it won't work.

This is an example which is on my background.js

function start() {

    var timeout = setTimeout( function() { start(); }, 1000*15);
    alert('test');
}

chrome.webNavigation.onCompleted.addListener(function(o) {

    start();

    }, {
      url: [
        {urlContains: 'http://www.example.com/in.php'},
        {urlContains: 'http://www.example.com/out.php'}
      ]
    }
);

If you reduce that timeout to 1000*13, it works.

This is my manifest.json

{
  "name": "Extension",
  "version": "0.0.7",
  "manifest_version": 2,
  "description": "Keeps proxy session alive",
  "homepage_url": "http://www.example.com",
  "icons": {
    "16": "icons/icon16-on.png",
    "48": "icons/icon48-on.png",
    "128": "icons/icon128-on.png"
  },
  "default_locale": "en",
  "background": {
    "scripts": [
      "src/bg/background.js"
    ],
    "persistent": false
  },
  "browser_action": {
    "default_icon": "icons/icon19.png",
    "default_title": "Example - Off",
    "default_popup": ""
  },
 "permissions": [
    "webNavigation", 
    "*://*/*",
    "https://*/*"
  ]
}

Any idea on what could be causing this oddness? I'm testing this on developer mode, BTW.

Thanks in advance!

EDIT

Code fixed:

manifest.json

I added "alarms" to the permissions

background.js

Added this event to listen to the alarms.create:

chrome.alarms.onAlarm.addListener(function(alarm){
    start();
});

Replaced the setTimeout function with the below line

chrome.alarms.create("Start", {periodInMinutes:1});

Hope this helps!

like image 221
badcom Avatar asked Oct 24 '14 00:10

badcom


People also ask

Is there a limit for setTimeout?

Maximum delay value Browsers including Internet Explorer, Chrome, Safari, and Firefox store the delay as a 32-bit signed integer internally. This causes an integer overflow when using delays larger than 2,147,483,647 ms (about 24.8 days), resulting in the timeout being executed immediately.

Is setTimeout deprecated?

We all know that passing a string to setTimeout (or setInterval ) is evil, because it is run in the global scope, has performance issues, is potentially insecure if you're injecting any parameters, etc. So doing this is definitely deprecated: setTimeout('doSomething(someVar)', 10000);

What happens when setTimeout is 0?

Invoking setTimeout with a callback, and zero as the second argument will schedule the callback to be run asynchronously, after the shortest possible delay - which will be around 10ms when the tab has focus and the JavaScript thread of execution is not busy.

Is JavaScript setTimeout blocking?

Explanation: setTimeout() is non-blocking which means it will run when the statements outside of it have executed and then after one second it will execute. All other statements that are not part of setTimeout() are blocking which means no other statement will execute before the current statement finishes.


1 Answers

I suspect the problem may with the automatic suspension of event pages after some period of inactivity. On my machine, onSuspend seems to called after ~10 seconds.

https://developer.chrome.com/extensions/event_pages#lifetime notes that

Once the event page has been idle a short time (a few seconds), the runtime.onSuspend event is dispatched. The event page has a few more seconds to handle this event before it is forcibly unloaded.

So, that may get you more around 13 seconds before the page is actually unloaded (giving you some cleanup time in onSuspend, I reckon). Then your page is unloaded and code initiated from there is no longer run.

https://developer.chrome.com/extensions/event_pages#transition says to use the alarms api for event pages instead of setTimeout.

like image 127
Brian Henry Avatar answered Sep 17 '22 20:09

Brian Henry