we are using require.js in our project and we need to override the setTimeout in line 705 , this is the code which we need to ignore/omit somehow this setTimeout at all(I mean run over it) ,the problem that if I change it in the open source code explicit when I change version the code will be lost,How should I override this setTimout from outside only for the require.js file and keep it as long as I use this lib, is it possible to do it in elegant way in JS globally ?
https://github.com/jrburke/requirejs/blob/master/require.js
This is line 705
//If still waiting on loads, and the waiting load is something
//other than a plugin resource, or there are still outstanding
//scripts, then just try back later.
if ((!expired || usingPathFallback) && stillLoading) {
//Something is still waiting to load. Wait for it, but only
//if a timeout is not already in effect.
if ((isBrowser || isWebWorker) && !checkLoadedTimeoutId) {
checkLoadedTimeoutId = setTimeout(function () {
checkLoadedTimeoutId = 0;
checkLoaded();
}, 50);
}
}
FYI ,The reason that we do it is Chrome: timeouts/interval suspended in background tabs?
You've stated your goal is to work around the throttling that Chrome performs on
setTimeout
for tabs that are in the background. I do not think it is a good idea to do so but if you must, then you should definitely patch RequireJS instead of messing withsetTimeout
globally. You said:This is true only if you do not use a sensible method to perform the change. It is possible to do it sensibly. For instance, you can use Gulp to take the
require.js
file installed innode_modules
(after you install RequireJS withnpm
) and produce a patched file inbuild
. Then you use this patched file in your application. Here is thegulpfile.js
:You need to have run
npm install gulp fs-extra bluebird requirejs
before running it. At any rate, you can use Gulp, you can use Grunt, or you can use any other system you want to perform a build. The points are:You have a reproducible and automated method to patch RequireJS. If you install a new version of RequireJS with
npm
, when you rebuild your software the patch is applied automatically, so long as the code of RequireJS does not change in a way that prevents applying the patch. See the next point for what happens if a change prevents applying the patch.This method is more robust than overriding
setTimeout
at runtime. Suppose James Burke decides in a newer version of RequireJS to renamecheckLoaded
tocheckDone
and renames the associated variables (so thatcheckLoadedTimeoutId
becomescheckDoneTimeoutId
). The gulpfile above will raise an exception when you run it again because it won't find the text to be replaced. You'll have to update the text to be replaced and the replacement so that the patch works with the new version of RequireJS. The benefit here is that you get an early warning that things have changed and that you need to review the patch. You won't have a surprise late in the game, perhaps after you've already delivered a new version of your software to clients.The methods that override
setTimeout
at run time will just silently fail to do their job. They'll be looking for a function that containscheckLoadedTimeoutId
, which won't exist anymore in the new version. So they will just let RequireJS behave the way it does by default. The failure will be a subtle one. (I've run RequireJS with the proposed custom versions ofsetTimeout
with a project that loads upwards of 50 modules when not optimized. I saw no discernible difference between RequireJS using the stocksetTimeout
and RequireJS using a customsetTimeout
.)This method does not slow down every use of
setTimeout
.setTimeout
is used by other code than RequireJS. No matter how you cut it, adding code in a custom replacement tosetTimeout
that starts looking for strings in each function passed to it will make all uses ofsetTimeout
slower.Other way to achieve it is making a ajax request of the library and patch it before load the library, but you will need to have loaded a way to make the request (vanilla js or jquery...)
The next code is an example of loading requirejs and patch it with a regexp before load it in the DOM.
You can override
setTimeout
and check if the function passed as callback contains a variable used in that function from require.js (checkLoadedTimeoutId
). If yes, call function immediately, otherwise call originalsetTimeout
function.Note that there are multiple issues with this code. If you pass a function to
setTimeout
which containscheckLoadedTimeoutId
, it will be executed immediately too. Also, if require.js code is minified and variables are renamed, it won't work.To sum up, there is no good way do this. Maybe try to find a different way to achieve what you want. Also be aware that, as Madara Uchiha said:
If you really need this... Try add before loading requirejs:
Should work in last Chrome, Firefox, IE if no requirejs minify provided... You need to rewrite function "isTimeoutIgnoredFunction" for browsers you support and for minified require.js file.
To see what string you can use:
But in some browsers it can just something like "Function".
If you have not many setTimeout's it can be suitable solution...