zoukankan      html  css  js  c++  java
  • 关于异步回调的一段代码及相关总结

    昨天遇到了一个问题,就是想在外部js里实现页面加载完了就执行js,类似于jquery中$或者window.onload,当然和window.onload还有所不同,因为window.onload是在图片啊其他的资源加载完了才开始执行的,而我想在尽可能快的执行,问题可以用一段代码来描叙:

     1 <html>
     2 <head>
     3 <script src="test.js“></script>
     4  
     5 </head>
     6 <body>
     7 
     8 <p id="hehe"></p>
     9 
    10 </body>
    11 
    12 </html>

    test.js代码:

    alert(document.getElementById("hehe");
    

      经过执行之后我们发现,alert返回null,按理应该返回object才对,因为我们alert了一个对象,之所以会产生这种情况,就是js先于domtree的建立,解决这种问题,当然一般我们可以换种写法,用window.onload,也可以按照yahoo优化网站的35条建议把<script>放到代码底部。也可以在外部js里强行僵化的用setTimeout(fn,seconds)来设置时间,但是博主不想这样,想一劳永逸并且尽可能优雅的解决问题,求助之后大神给了如下代码:

     1 var isReady = false;
     2 var readyList = [];
     3 
     4 function ready(fn) {
     5   if (isReady) {
     6     setTimeout(function () {
     7       fn()
     8     }, 0);
     9     return;
    10   }
    11   readyList.push(fn);
    12 }
    13 
    14 function setReady() {
    15   if (isReady) {
    16     return;
    17   }
    18 
    19   isReady = true;
    20   for (var i = 0, n = readyList.length; i < n; i++) {
    21     readyList[i]();
    22   }
    23   readyList.length = 0;
    24 }
    25 
    26 (function () {
    27   if (document.readyState === 'complete') {
    28     setTimeout(setReady, 0);
    29   } else {
    30     document.addEventListener('DOMContentLoaded', setReady);
    31     window.addEventListener('load', setReady);
    32   }
    33 }());

    我一开始没有理解异步回调,所以百思不得其解,后来有幸有人告诉我这是回调这才豁然开朗,其实setTimeout()这不也是一种异步回调的写法吗?

    上述代码中

    document.addEventListener('DOMContentLoaded', setReady);
    window.addEventListener('load', setReady);这就是异步回调addEventListener和setTimeout都是异步回调的写法,在setTimeout中setTimeout(fn,seconds)但seconds条件未满足即此条件未触发时,js程序挂起,页面构建domtree渲染,但事件发生之后,中断页面渲染,执行js代码,类似的可以理解addEventListener函数。异步回调之后就可以达到我们的目的

    这就是异步回调 addEventListener和setTimeout都是异步回调的写法,在setTimeout中setTimeout(fn,seconds)但seconds条件未满足即此条件未触发时,js程序挂起,页面构建domtree渲染,但事件发生之后,中断页面渲染,执行js代码,类似的可以理解addEventListener函数。 异步回调之后就可以达到我们的目的,大神给的代码中,有队列还有全局标记,功能很多,处理很全面,为了理解核心部分,我做一个简化,html代码不变,js代码改为:

     1 //var isReady = false;
     2 //var readyList = [];
     3 var a={};
     4 
     5 function ready(fn) {
     6   //if (isReady) {
     7  //   setTimeout(function () {
     8   //    fn()
     9  //   }, 0);
    10   //  return;
    11  // }
    12 a.fn=fn;
    13 }
    14 
    15 function setReady() {
    16   a.fn();
    17 }
    18 
    19 (function () {
    20   if (document.readyState === 'complete') {
    21     setTimeout(setReady, 0);
    22   } else {
    23     document.addEventListener('DOMContentLoaded', setReady);
    24     window.addEventListener('load', setReady);
    25   }
    26 }());

    这样注释掉一些部分理解起来就容易了,但是请注意,这样因为有两个事件和两个回调会执行两次fn()。

    关于回调还可以参加阮一峰老师的博客,写的很好http://www.ruanyifeng.com/blog/2012/12/asynchronous%EF%BC%BFjavascript.html 我打算转载过来。

  • 相关阅读:
    实战:当jquery遇上了json
    验证文本域字符个数的正则表达式
    分布式缓存方案:Memcached初探
    Asp.Net Forms验证(自定义、角色提供程序、单点登录) [转]
    C#3.0扩展方法[转]
    HttpWebRequest调用web服务的代码
    解决User.Identity.IsAuthenticated==false 或User.Identity.Name==string.empty的问题[转]
    微软Asp.net Ajax 1.0的AutoComplete控件的几处修正和增强 [转]
    LINQ体验(5)——LINQ语句之Select/Distinct和Count/Sum/Min/Max/Avg(转)
    c# Linq 的分页[转]
  • 原文地址:https://www.cnblogs.com/admos/p/4427852.html
Copyright © 2011-2022 走看看