关于异步回调的一段代码及相关总结

昨天遇到了一个问题,就是想在外部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 我打算转载过来。

时间: 2024-10-08 02:11:31

关于异步回调的一段代码及相关总结的相关文章

java中 synchronized 的使用,确保异步执行某一段代码。

最近看了个有关访问网络url和下载的例子,里面有几个synchronized的地方,系统学习下,以下内容很重要,记下来. Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行.另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块. 二.然而,当一个线程访问object的一个synchroniz

State Threads——异步回调的线性实现

State Threads——异步回调的线性实现 原文链接:http://coolshell.cn/articles/12012.html 本文的标题看起来有点拗口,其实State Threads库就是在单线程中使用同步编程思想来实现异步的处理流程,从而实现单线程能并发处理成百上千个请求,而且每个请求的处理过程是线性的,没有使用晦涩难懂的callback机制来衔接处理流程. ST (State Threads) 库提供了一种高性能.可扩展服务器(比如web server.proxy server

Tornado 框架中异步与非阻塞编程代码说明

在tornad官方文档的Docs>User's guide>Asynchronous and non-Blocking I/O部分,文中提供了几段示例代码: a.同步请求代码 from tornado.httpclient import HTTPClient def synchronous_fetch(url):     http_client = HTTPClient()     response = http_client.fetch(url)     return response.bo

异步回调

作者:禅楼望月(http://www.cnblogs.com/yaoyinglong) 1.开始讲故事: 午饭的时候到了,可是天气太冷,根本不想出办公室的门,于是你拨通了XXX饭店的订餐电话"喂!你好,我是XXX公司的小菜,我要点--".然后以继续干你的工作了,过了一会儿,"你好,是XXX公司的小菜吧,你的午饭到了".这个过程便是一个典型的异步回调.那么我们来看一下,这个里面有什么必须的条件: XXX饭店必须有送饭的业务: 你必须接受饭菜,如果你不接受饭菜,你就吃不

深入理解yield(三):yield与基于Tornado的异步回调

转自:http://beginman.cn/python/2015/04/06/yield-via-Tornado/ 作者:BeginMan 版权声明:本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接. 发表于 2015-04-06 在深入理解yield(二):yield与协程 和深入理解yield(一):yield原理已经对yield原理及在python中的运用了解了很多,那么接下来就要结合Tornado,进行python异步的分析. 一.异步的实

异步回调方式的讨论

很多时候需要异步操作来避免阻塞当前线程,而异步操作的结果需要通过回调告知调用者,而回调的方式有多种,且不同语言支持的情况也不一样. 回调机制是在某个时间发生前准备好的一段代码,事件一旦发生,系就会执行相应的代码.因此回调有两个主要部分组成:(1)注册过程 (2)事件发生时需要执行的代码. 实现回调机制的途径有一下几大类: 1.注册对象和回调方法 (1)目标-动作对:异步调用时,简单保存目标对象指针和其回调处理方法的指针,当异步操作结束后,被调用对象会通过二者找到回调的入口,并执行回调. (2)

Java异步回调

作者:禅楼望月(http://www.cnblogs.com/yaoyinglong) 1.开始讲故事: 午饭的时候到了,可是天气太冷,根本不想出办公室的门,于是你拨通了XXX饭店的订餐电话“喂!你好,我是XXX公司的小菜,我要点……”.然后以继续干你的工作了,过了一会儿,“你好,是XXX公司的小菜吧,你的午饭到了”.这个过程便是一个典型的异步回调.那么我们来看一下,这个里面有什么必须的条件: XXX饭店必须有送饭的业务: 你必须接受饭菜,如果你不接受饭菜,你就吃不到饭了. 这两个协议双方都必须

python第三十七天,GIL全局解释器锁*****,线程池与进程池 同步异步,阻塞与非阻塞,异步回调

GIL全局解释器锁 1.什么是GIL 官方解释:'''In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython’s memory management is not thread-safe

C#:同步调用、异步调用、异步回调

ylbtech-C#:同步调用.异步调用.异步回调 1.返回顶部 1. 本文将主要通过“同步调用”.“异步调用”.“异步回调”三个示例来讲解在用委托执行同一个“加法类”的时候的的区别和利弊. 首先,通过代码定义一个委托和下面三个示例将要调用的方法: public delegate int AddHandler(int a,int b);    public class 加法类    {        public static int Add(int a, int b)        {