当$(function())调用多次时,jQuery的函数$(function())的执行顺序

Jac*_*kRo 5 javascript jquery jquery-3

像这样的代码:

$(window.document).ready(function () {
    window.alert('alert 1');
});

$(function () {
    window.alert('alert 2');
});

$(function () {
   window.alert('alert 3');
});
Run Code Online (Sandbox Code Playgroud)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo2</title>
    <script src="jquery-3.1.1.js"></script>
    <script src="demo2.js"></script>
</head>
<body>

</body>
</html>
Run Code Online (Sandbox Code Playgroud)

当我执行上面的代码时,页面的警报顺序有时是:警报1,警报2,警报3,有时是:警报1,警报3,警报2.任何人都可以告诉我为什么?

gue*_*314 3

在jQuery 版本 3.1.1 的行3930中,处理在已加载后调用。在第 3938 行被调用,没有设置持续时间并附有注释3947.ready()documentjQuery.readysetTimeout

// Handle it asynchronously to allow scripts the opportunity to delay ready
Run Code Online (Sandbox Code Playgroud)

这将解释如何window.alert('alert 3')可能在之前被调用window.alert('alert 2')


// Catch cases where $(document).ready() is called
// after the browser event has already occurred.
// Support: IE <=9 - 10 only
// Older IE sometimes signals "interactive" too soon
if ( document.readyState === "complete" ||
    ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {

    // Handle it asynchronously to allow scripts the opportunity to delay ready
    window.setTimeout( jQuery.ready ); // Line 3938

} else {

    // Use the handy event callback
    document.addEventListener( "DOMContentLoaded", completed );

    // A fallback to window.onload, that will always work
    window.addEventListener( "load", completed );
}
Run Code Online (Sandbox Code Playgroud)

以下 stacksnippet 应该重现 OP 描述的结果

// Handle it asynchronously to allow scripts the opportunity to delay ready
Run Code Online (Sandbox Code Playgroud)

另请参阅completedLine 的功能3924

// The ready event handler and self cleanup method
function completed() {
    document.removeEventListener( "DOMContentLoaded", completed );
    window.removeEventListener( "load", completed );
    jQuery.ready();
}
Run Code Online (Sandbox Code Playgroud)

请参阅 plnkr http://plnkr.co/edit/C0leBhYJq8CMh7WqndzH?p=preview版本 1


编辑、更新

为了确保函数的执行顺序,.ready()您可以从函数调用返回一个承诺,使用.then()内部单个.ready()调用来调用全局或先前在.ready()处理程序中定义的函数。

// Catch cases where $(document).ready() is called
// after the browser event has already occurred.
// Support: IE <=9 - 10 only
// Older IE sometimes signals "interactive" too soon
if ( document.readyState === "complete" ||
    ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {

    // Handle it asynchronously to allow scripts the opportunity to delay ready
    window.setTimeout( jQuery.ready ); // Line 3938

} else {

    // Use the handy event callback
    document.addEventListener( "DOMContentLoaded", completed );

    // A fallback to window.onload, that will always work
    window.addEventListener( "load", completed );
}
Run Code Online (Sandbox Code Playgroud)