$(document).ready inside $(document).ready
Asked Answered
B

3

11

I found code in my codebase that has $(document).ready(function() {...} inside of another $(document).ready(function() {...}

e.g.

$(document).ready(function() {      

    // 20 lines... 

    $(document).ready(function() {
        foo()
    }

    // 200 lines...
}

function foo() {...}

I want to understand the order of execution so I can safely refactor out this nested callback. The outer callback seems to continue executing before the inner callback executes. Is the outer callback guaranteed to finish before the inner callback gets called?

Bully answered 14/3, 2014 at 20:11 Comment(4)
Post this mysterious code you speak of.Madlynmadman
Interesting, but why would you do this?Glanti
Isn't this assigning a listener to the document's ready event after the event has fired? I would have expected that code (within the outer function) to never execute.Cadastre
@MichaelZalla, I recently saw a case where code was (poorly) refactored from an IIFE into a document.ready callback and the original document.ready code was left as-is. Thankfully things kept working because that would have been a nightmare to debug.Prentice
P
14

Is the outer callback guaranteed to finish before the inner callback gets called?

Yes.

The way document.ready works is that it will wait for the readystatechange event to fire as being ready before the callback gets called, however it also runs setTimeout if the readystatechange event has already fired.

This means that code such as:

$(function () {
    a();
    $(b);
    c();
});

Where a, b, and c are all functions will execute in the order of:

  1. a
  2. c
  3. b

On a related note, people will question why you would want to run a document.ready call inside another document.ready call, and the short answer is that you wouldn't.

The only gain is that $(callback) is a bit more convenient to write than:

setTimeout(callback, 0);
Prentice answered 14/3, 2014 at 20:18 Comment(1)
you can observe this here code.jquery.com/jquery-1.11.0.js on line 3411. promises are also usedRipplet
S
1

You should remove the inner $(document).ready and assign a name to that callback. Then call it as the last line the outer callback.

Silk answered 14/3, 2014 at 20:18 Comment(0)
D
-2

Yes. Event listeners are stored in a stack, and are just popped off one at a time when the event is triggered. This 'ready' listener just adds another 'ready' listener to the end of the stack. So when the first (outer) one is all done executing, the browser continues down the stack... until it gets to the second (inner) one, and then it executes that.

Disaccredit answered 14/3, 2014 at 20:20 Comment(1)
If the code were document.addEventListener('readystatechange', callback, false) this answer might be the case, however the way jQuery handles document.ready involves a lot of indirection and tricks to get things to work nicely cross-browser. It doesn't actually store subsequent ready callbacks in a stack once the first callback has executed.Prentice

© 2022 - 2024 — McMap. All rights reserved.