异步函数的类型
1.异步的I/O函数
例如一个同步的I/O请求是这样的
function ajaxasyn() {
var url = 'www.baidu.com';
var ajaxRequest = new XMLHttpRequest;
ajaxRequest.open('GET', url);
ajaxRequest.send(null);
while (ajaxRequest.readyState === XMLHttpRequest.UNSENT) {
//readystate
}
}
说明:写到这里的时候我犯了一个错误,因为这些函数我都是在node环境下测试,这时控制台就报了一个错误:“XMLHttpRequest is not defined” 后来查阅了相关资料才知道,XMLHTTPRequest是浏览器内置的一个对象,node的关于http是采用http模块了。 并且在IE7之前是不支持XHR的,在IE7之前创建XHR对象需要用ActiveXObject。 readyState有5种状态:
- 0(UNSENT):未初始化
- 1(OPENED):启动:已经调用了open()方法
- 2(HEADERS_RECEIVED):发送:已经调用了send()方法,但是尚未收到响应
- 3:接收(LOADING):已经接收到了部分数据,但是没有接收完成,responseText已经有部分数据
- 4:完成(DONE):已经完全接收了数据
因此要把上面的同步事件变成一个异步事件,其实就是加一个监听事件,我们不必等这个过程,让cpu先完成后面的事情,直到onreadystatechange事件触发。 因为XHR有一个onreadystatechange事件,因为我们可以很好的写异步函数。
采用DOM 0级事件处理程序的编写方式,因为并非所有浏览器都支持DOM 2级方法
Dom 1级方法就是div.onclick=function(){} Dom 2级方法就是div.addEventListener('click',funciont(){}) 和removeEventListener;(除ie外,ie是attachEvent('onclick',funciton(){})和detachEvent())
function ajaxsync() {
var url = 'www.baidu.com';
var xhr = new XMLHttpRequest;
xhr.open('GET', url);
xhr.send(null);
xhr.onreadyStatechange = function() {
if (readyState == 4) {
//4:done
//再检测status
if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) {
//2xx表示成功或者知道了,304表示要客户端使用缓存
}
}
}
}
另外值得说明的是在浏览器中console.log和nodejs中是否是异步的:
Webkit中console.log()并没有立即对拍摄对象快照,它只存储了一个指向对象的引用,因此输出是"bar" Node 中是严格同步的,因此输出是{}
异步的计时函数
上一节说了setTimeout并不精确,setInterval是指多少ms执行一次函数,这个函数也不精确。
因此在Node中,最好用process.nextTick,process.nextTick事件触发频率可以超过10万次/秒 一些现代浏览器(IE9+)有 requestAnimationFrame,此函数有两个目标:它允许以60+帧/秒的速度运行javascript动画;同时避免后台选项卡运行这些动画,节约CPU周期。
因此在支持requestAnimationFrame的浏览器中,使用requestAnimationFrame;不支持的话就用setTimeout。