5

I need to override the following code

Here the function will be executed in the next tick

req.nextTick = typeof setTimeout !== 'undefined' ? function (fn) {
    setTimeout(fn, 5);
} : function (fn) { fn(); }; 

with this,

window.require.nextTick = function(fn) { fn(); };

Since the function will be called immediately, Does in this case it won’t be executed on next tick ?

07_05_GuyT
  • 2,787
  • 14
  • 43
  • 88

3 Answers3

2

if I change the code to the second option whethaer It will be problematic and if yes why???

I don't recommend making that change, because it can be problematic, generally speaking. The documentation for require.nextTick (which appears just before the function definition) says:

Execute something after the current tick of the event loop.

Calling fn synchronously violates the specification that execution should happen "after the current tick". (See the end of my answer for a possible objection here.)

If you wonder why it may be a problem consider that RequireJS listens to DOM events. One thing that having a function like require.nextTick does is give a chance to event handlers to run. If you set require.nextTick to execute its function synchronously then you are not giving a chance to event handlers to run. In some cases this could cause RequireJS to cease working properly.

At this point, one might object the definition of nextTick is such that it is okay to have it call fn synchronously, because if setTimeout is not defined, then it does call fn synchronously:

req.nextTick = typeof setTimeout !== 'undefined' ? function (fn) {
    setTimeout(fn, 4);
} : function (fn) { fn(); };

I think this is meant for unusual cases, not the run-of-the-mill situation where modules are loaded through HTTP requests asynchronously. In some cases, like perhaps embedded devices that lack the JS environment provided by browsers or Node.js, the only way to execute a piece of software that uses RequireJS is to load an optimized bundle that has gone through r.js and include require.js in the bundle. In a case like this, having nextTick call fn synchronously would be moot because, by the time RequireJS executes, all the modules have been loaded already.

Louis
  • 146,715
  • 28
  • 274
  • 320
1

If you have a function like this:

window.require.nextTick = function(fn) { fn(); };

every time you call window.require.nextTick(), fn() will be executed immediately.

if I change the code to the second option whethaer It will be problematic

No, it won't cause any problems. The only difference between the first and second code is that in the first fn() is called after 5 milliseconds and in the second it's called immediately. In both examples fn() will be called every time you call window.require.nextTick().

Michał Perłakowski
  • 88,409
  • 26
  • 156
  • 177
1

There is something fundamentally wrong with the original function. It behaves very differently if setTimeout is undefined.

Javascript runs on an event loop. Your Javascript code runs until it is done, and other Javascript code will wait its turn in the "queue". For example, an event listener for a user event (like clicking a button) gets "queued" and waits for the current code to finish.

Your nextTick function is presumably meant to add a function to the "queue" so it will be executed later by the event loop. This is sometimes useful. For example, you can have your own event emitter and want to queue your own event.

Your nextTick function is therefore broken if setTimeout is undefined. It will execute the function now instead of adding it to the "queue". This will lead to totally different behavior, which means bugs that only occur for certain browsers.

Please fix your code to use this instead:

window.require.nextTick = function(fn) { setTimeout(fn, 5) };

and ignore browsers that don't implement setTimeout. They can have a big fat error instead of strange subtle bugs.

Just for the record, setTimeout works in all major browsers for the past 20 years or so. It is supported back to IE4! So this conditional is completely unnecessary.

chowey
  • 9,138
  • 6
  • 54
  • 84