js同步和异步的问题

 

1.ie动态加载js文件时,它默认就为同步,可以不用设置同步(也可直调用Skip.includeJsSrc())
2.ff动态加载js文件时,它默认为异步,要设置成同步,加载完直接调用才不会出错
3.无论ie还是ff在动态加载js内容时,没有请求服务器,不会存在异步问题
注:无论ie还是ff在页面加载js时(即执行整个页面),都是为同步的加载,除非设置script的属性defer="true"(此属性好像也只是对ie有效)

 

=======================================================================================

===

================================================================

 

动态加载js文件

一.直接加载

<body>

<div id="divId"></div>

<script>

     //1.动态创建js

     var rootObject=document.getElementById("divId");
     var oScript = document.createElement( "script" );
     oScript.type = "text/javascript";
     oScript.src = test.js; //test.js方法中有一个方法function test(){alert("test");}
     rootObject.appendChild(oScript);

 

     //2.调用js

     test();//在ie中不会出错,在firefox会出错,因为firefox默认为异步加载(在向服务器请求加载test.js文件的同时,继续向下执行了,调用test()方法,就自然找不到这个方法)

</script>

</body>

二.同步加载

<body>

<div id="divId"></div>

<script>

(function(){

 

Skip={

//获取XMLHttpRequest对象(提供客户端同http服务器通讯的协议)

getXmlHttpRequest:function ()
{
    if ( window.XMLHttpRequest ) // 除了IE外的其它浏览器
           return new XMLHttpRequest() ;
    else if ( window.ActiveXObject ) // IE
            return new ActiveXObject("MsXml2.XmlHttp") ;

},

 

 //导入内容
includeJsText :function (rootObject,jsText)
       {
        if ( rootObject != null ){
                var oScript = document.createElement( "script" );
             oScript.type = "text/javascript";
            //oScript.id = sId;
            //oScript.src = fileUrl;
            //oScript.defer = true;
            oScript.text = jsText;
            rootObject.appendChild(oScript);
            //alert(oScript.text);
        }
       },


 //导入文件
includeJsSrc :function (rootObject, fileUrl)
      {
        if ( rootObject != null ){
                var oScript = document.createElement( "script" );
             oScript.type = "text/javascript";
            oScript.src = fileUrl;
            rootObject.appendChild(oScript);
       }
      },

 

//同步加载
addJs:function(rootObject, url){

        var oXmlHttp = this.GetHttpRequest() ;
       
        oXmlHttp.onreadystatechange = function()  //其实当在第二次调用导入js时,因为在浏览器当中存在这个*.js文件了,它就不在访问服务器,也就不在执行这个方法了,这个方法也只有设置成异步时才用到
       
        {
            if ( oXmlHttp.readyState == 4 ) //当执行完成以后(返回了响应)所要执行的
       
            {
                if ( oXmlHttp.status == 200 || oXmlHttp.status == 304 ) //200有读取对应的url文件,404表示不存在这个文件
       
                {
       
                    includeJsSrc( rootObject, url);
                }
       
                else
       
                {
                    alert( 'XML request error: ' + oXmlHttp.statusText + ' (' + oXmlHttp.status + ')' ) ;
       
                }
       
            }

         }
        
         //1.True 表示脚本会在 send() 方法之后继续执行,而不等待来自服务器的响应,并且在open()方法当中有调用到onreadystatechange()这个方法。通过把该参数设置为 "false",可以省去额外的 onreadystatechange 代码,它表示服务器返回响应后才执行send()后面的方法.
         //2.同步执行oXmlHttp.send()方法后oXmlHttp.responseText有返回对应的内容,而异步还是为空,只有在oXmlHttp.readyState == 4时才有内容,反正同步的在oXmlHttp.send()后的操作就相当于oXmlHttp.readyState == 4下的操作,它相当于只有了这一种状态.
      oXmlHttp.open('GET', url, false); //url为js文件时,ie会自动生成 '<script src="*.js" type="text/javascript"></script>',ff不会 
      oXmlHttp.send(null);
      includeJsText(rootObject,oXmlHttp.responseText);
      }
}

};
 var rootObject=document.getElementById("divId");

 Skip.addJs(rootObject,"test.js")//test.js文件中含有funciotn test(){alert("test");}

test();//即使马上调用也不会出错了.


})();

 

</script>

</body>

 

### JavaScript 同步异步编程的区别及工作原理 JavaScript同步异步编程模型是基于其单线程执行环境而设计的,这种设计使得代码执行顺序资源管理必须非常谨慎。理解同步异步的关键在于事件循环(Event Loop)机制以及任务队列(Task Queue)的作用。 #### 同步编程 在同步编程中,代码按照顺序依次执行。每条语句必须等待前一条语句执行完毕后才能开始执行。这种模式简单直观,但存在明显的缺点:如果某段代码执行时间较长,例如进行复杂的计算或等待 I/O 操作完成,主线程会被阻塞,导致整个程序无法响应用户交互或渲染更新。 例如: ```javascript console.log("Step 1"); console.log("Step 2"); ``` 上述代码会依次输出 "Step 1" "Step 2",没有任何延迟[^5]。 #### 异步编程 异步编程允许某些操作在后台运行,而不会阻塞主线程。常见的异步操作包括网络请求(如 `fetch`)、定时器(如 `setTimeout`、`setInterval`)以及文件读写等。JavaScript 使用回调函数、Promise 对象以及 `async/await` 语法来处理异步逻辑,从而实现非阻塞执行。 异步任务通常被放入任务队列中,当主线程空闲时,事件循环会从任务队列中取出下一个任务并执行。这种机制确保了即使有耗时操作,也不会影响其他代码的执行。 一个典型的异步示例是使用 `setTimeout`: ```javascript console.log("1. 开始"); setTimeout(() => { console.log("3. 异步任务完成,执行回调"); }, 2000); console.log("2. 继续执行主线程代码"); ``` 输出结果为: ``` 1. 开始 2. 继续执行主线程代码 3. 异步任务完成,执行回调 ``` 这说明异步任务不会阻塞主线程的执行流程。 #### 工作原理:事件循环与任务队列 JavaScript 引擎通过事件循环机制协调同步异步任务的执行。其核心流程如下: 1. **主线程执行同步任务**:所有同步代码按顺序执行。 2. **异步任务注册回调**:异步操作(如 `setTimeout`)将回调函数注册到任务队列中。 3. **事件循环检查任务队列**:当主线程为空时,事件循环从任务队列中取出最早的任务并执行其回调函数。 此外,现代 JavaScript 支持使用 `Promise` `async/await` 来更优雅地组织异步逻辑。`Promise` 提供了一种链式调用的方式,避免了“回调地狱”问题;而 `async/await` 则让异步代码看起来更像同步代码,提高了可读性可维护性[^2]。 #### 总结 - **同步编程**:代码顺序执行,容易理解但可能造成阻塞。 - **异步编程**:利用事件循环任务队列实现非阻塞执行,适用于耗时操作。 - **关键机制**:事件循环负责调度任务队列中的异步回调进入主线程执行。 JavaScript异步特性使其能够在单线程环境下高效处理并发任务,同时保持良好的用户体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值