异步的来由
js的执行环境是单线程的,事件是按照顺序来执行的,只有当前事件执行完毕以后,才会去执行下一个事件,这样有时候会导致js执行阻塞。
异步就出来了,当js执行的时候,碰到了异步事件,就会把这个异步事件放入一个event loop(是一个程序结构,用于等待和发送消息和事件)里面,当同步事件执行完毕以后,就会去执行event loop里面的事件。
js实现异步的方法
为了实现异步,我了解的js有一下几种方法(可能还有其他的)
一 回调
回调,就是把一个函数当作一个参数传入另外一个函数,这个参数为callback,注意,回调函数不一定是异步的,也有同步的回调函数,一般是调用setTimeout,setInterval来实现异步
1
2
3
4
5
6
7
8
9
10
11
12
13
14 function funA(callback){
console.log("a")
setTimeout(function(){
callback();
}, 1000);
}
function funC(){
console.log("c")
}
function funcB(){
console.log("b")
}
funA(funcB)
funC()
运行打印结果:
1
2
3
=>a
=>c
=>b
二事件监听
函数的执行依赖某个事件是否发生。
1
2
3
4
function handleEvent: (e) {
console.log(e)
}
document.body.addEventListener('click', handleEvent)
当监听到click事件的时候,才去执行handleEvent函数
三发布订阅
上一个事件的结果作为通知,让订阅的函数得到通知,执行
四 ajax
ajax执行请求的时候,不会堵塞,一直等待请求,而是等有了结果再来执行之后的代码,ajax的异步实现,其实是封装了XMLHttpRequest。
发送一个请求,大概要以下经历:
1.打开一个请求,此时并不会发送请求
1 | XMLHttpRequest.open(method,url,async,user,password) |
2.设置请求头部信息
1 | XMLHttpRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=gb2312") |
3.发送请求
1 | XMLHttpRequest.send(data); |
以上,是一个简单的请求发送。
XMLHttpRequest有readyState这个属性,它有四个值:
0:为初始化 已经创建好了XMLHttpRequest对象xml,但是还没有初始化
1:已经初始化好了XMLHttpRequest对象xml,准备好要发送了
2:send被调用 请求已经发送 但是还没有收到服务器的响应
3:浏览器正在接受服务器发送过来的请求 但是还没有接受完
4:浏览器已经 接受请求完毕
XMLHttpRequest还有一个onreadystatechange方法,每当readyState改变的时候都会触发这个方法,所以可以根据readyState的值来执行不同的函数。1
2
3
4
5
6
7
8
9
10
11
12
13if(window.XHRHttpRequest){
var xhr = new XMLHttpRequest();
}else{
var xhr = new ActiveObject("Microsoft.XMLHTTP");
}
xhr.open('GET','url',true);
xhr.send(null);
xhr.onreadystatechange=function () {
if(xml.readyState==4){
// 当readyState==4的时候请求完毕。
callback()
}
}
ajax主要是通过onreadystatechange和readyState来实现异步,根据返回值来调用不同的回调函数
五 promise
promise是es6的方法,原来的异步其实都是回调函数的方式来实现,一层嵌套一层,代码不够优雅,promise让这种这种异步更加优雅,它采用链式操作的方法来实现异步。
六 ansyc,await
待续。。。