ajax请求确实是异步的,不过这请求是由浏览器新开一个线程请求,当请求的状态变更时,如果先前已设置回调,这异步线程就产生状态变更事件放到JavaScript引擎的处理队列中等待处理。见:http://www.phpv.net/html/1700.html
你有事去隔壁寝室找同学,发现人不在,你怎么办呢?
方法1,每隔几分钟再去趟隔壁寝室,看人在不
方法2,拜托与他同寝室的人,看到他回来时叫一下你
前者是轮询,后者是回调。
那你说,我直接在隔壁寝室等到同学回来可以吗?
可以啊,只不过这样原本你可以省下时间做其他事,现在必须浪费在等待上了。把原来的非阻塞的异步调用变成了阻塞的同步调用。
javascript的回调是在异步调用场景下使用的,使用回调性能好于轮询。
“我现在出发,到了通知你”这是一个异步的流程,“我出发”这个过程中(函数执行),“你”可以去做任何事,“到了”(函数执行完毕)“通知你”(回调)进行之后的流程。
函数也是对象
想弄明白回调函数,首先的清楚地明白函数的规则。在javascript中,函数是比较奇怪的,但它确确实实是对象。确切地说,函数是用Function()构造函数创建的Function对象。Function对象包含一个字符串,字符串包含函数的javascript代码。假如你是从C语言或者Java语言转过来的,这也许看起来很奇怪,代码怎么可能是字符串?但是对于javascript来说,这很平常。数据和代码之间的区别是很模糊的。
传统函数以参数形式输入数据,并且使用返回语句返回值。理论上,在函数结尾处有一个return返回语句,结构上就是:一个输入点和一个输出点。这比较容易理解,函数本质上就是输入和输出之间实现过程的映射。
但是,当函数的实现过程非常漫长,你是选择等待函数完成处理,还是使用回调函数进行异步处理呢?这种情况下,使用回调函数变得至关重要,例如:AJAX请求。若是使用回调函数进行处理,代码就可以继续进行其他任务,而无需空等。实际开发中,经常在javascript中使用异步调用,甚至在这里强烈推荐使用!
下面有个更加全面的使用AJAX加载XML文件的示例,并且使用了call()函数,在请求对象(requested object)上下文中调用回调函数。
从《Head First Ajax》理解关于回调函数
回调函数是一个函数的引用,不是调用,所以应确保不要在函数名后加上括号。
问:你能再解释一下什么是回调函数吗?
答:回调函数是另外某件事结束时执行的一个函数。在Ajax中,回调函数就是服务器对一个请求对象作出响应时调用的函数。浏览器会在某个时刻”回调”这个函数。
问:那就是说,当服务器结束对一个请求的处理时就会执行一个回调函数,对吗?
答:不是这样的,实际上每次服务器响应请求时就会由浏览器调用回调函数,即使此时服务器并没有完全处理完请求。大多数服务器都会做多次响应,指示接收到请求,或者正在处理请求,或者已经处理完请求。
问:就是因为这个原因,这个请求属性才被命名为onreadystatechange吗?
答:完全正确。每次服务器响应一个请求时,它会把请求对象readyState属性设置为一个不同的值。所以我们要特别注意这个属性,来确定服务器何时处理完我们发送给它的请求。
问:这么说来,处理完请求时服务器会调用displayDetails(),是吗?
答:不对,实际上是由浏览器调用这个函数。服务器所做的只是更新请求对象的readyState属性。每次这个属性发生变化时,浏览器就会调用onreadystatechange属性中指定的函数。
问:readyState属性是什么?
答:这是一个数,指示服务器处理进行到哪个阶段。初始值为0,服务器处理完一个请求时,这个属性的值将是4.
问:为什么每一次都必须检查呢?
答:因为每次准备状态改变时浏览器都会运行回调函数。由于服务器接收到请求时会把这个值设置为1,而在处理请求时有可能把这个值设置为2或3,所以除非readyState等于4,否则无法确定服务器是否处理完请求。
问:那么status属性呢?
答:这是HTTP状态码,如404就代表禁止访问,200代表成功。对请求对象做任何处理之前一定要确保状态码为200。
使用Ajax异步调用的时候,
需要触发readystatechange事件,然后检测readyState属性即可。这个属性有五个值:
当请求发送到服务器端, 收到响应后, 响应的数据会自动填充 XHR对象的属性。 那么一共有四个属性:
接受响应之后, 第一步检查 status属性, 以确定响应已经成功返回。 一般而已 HTTP状
态代码为 200作为成功的标志。除了成功的状态代码,还有一些别的: