ajax的同步异步易混淆点

文章目录

基础

浏览器是多线程的,一个进程有多个线程。js是单线程,模拟异步。所以分为主任务队列,等待任务队列

【readyState值】
//=>0 刚开始创建ajax对象,还没有发送
//=>1 已经执行了open操作
//=>2 已经发送ajax请求,已经收到响应头信息但还没收到响应主体
//=>3 响应主体正在返回
//=>4 响应主体已经完全被客户端接收

var xhr = new XMLHttpRequest() //一  创建ajax对象
console.log(xhr.readyState) //0
xhr.open("get", 'http://localhost:3000') //二 打开请求
console.log(xhr.readyState)// 1
xhr.setRequestHeader("name", "wangyue") //只能放在opne后面且不可以是中文
xhr.onreadystatechange = () => { //三 给该属性绑定事件监听 
    if (xhr.status === 200 && xhr.readyState == 4) {
        let responseText = xhr.response
        console.log (responseText)
    }
};
xhr.send() //四 发送请求
console.log(xhr.readyState)//返回结果为1 因为先执行主任务队列,执行console的时候还在1,信息刚发出还没有返回头信息

在这里插入图片描述
因为先执行主任务队列,之后再执行等待队列

例1

var xhr = new XMLHttpRequest()
xhr.open("get", 'http://localhost:3000')
xhr.onreadystatechange = () => {
    if (xhr.readyState == 2) {
        console.log (1)
    }
    if (xhr.readyState == 4) {
        console.log (2)
    }
};
xhr.send()
console.log(3)

结果是 3 1 2
异步,先执行主任务队列的console.log(3),此时的readyState为1.刚发送ajax请求,没到2。主任务队列执行完执行等待队列,当readyState为2时打印1,为4时打印2

例2

var xhr = new XMLHttpRequest()
xhr.open("get", 'http://localhost:3000')
xhr.send()
//此时readyState为1
xhr.onreadystatechange = () => {
    if (xhr.readyState == 2) {
        console.log (1)
    }
    if (xhr.readyState == 4) {
        console.log (2)
    }
};
console.log(3)

结果仍然是3 1 2
先执行主任务队列,一直到console.log(3)都是主任务队列。然后再等待队列

例3

var xhr = new XMLHttpRequest()
xhr.open("get", 'http://localhost:3000', true) //同步
xhr.onreadystatechange = () => { //监听前的状态是1
    if (xhr.readyState == 2) {
        console.log (1)
    }
    if (xhr.readyState == 4) {
        console.log (2)
    }
};
xhr.send() //只要ajax请求这件事完成,什么都不能做,4才算完成
console.log(3)

此时结果是2 3
当状态为2确实触发了onreadystatechange方法,但是在ajax完成之前什么都不能干,主任务队列没空去执行console.log(2),到4结束了所以执行console.log(2)
当ajax任务开始,由于是同步编程,祝任务队列在状态没有编程4(任务结束)之前一直被这件事占着,其他事情都做不了(当服务器把响应头返回的时候,状态为2,触发了事件,但是由于主任务队列没有完成,被占着,绑定的方法无法执行)

【图解】
在这里插入图片描述
事件绑定把那些方法放到等待队列里,当状态改变执行等待队列的方法。只有ajax请求结束才会去执行等待队列里的内容,结束时是4了,所以只执行4的

例4

var xhr = new XMLHttpRequest()
xhr.open("get", 'http://localhost:3000', true) 
xhr.send() //开始请求,状态不为4其他都执行不了,此时等待里没有东西
//事件绑定前已经是4
xhr.onreadystatechange = () => { //又不会变为5,所以不执行
    if (xhr.readyState == 2) {
        console.log (1)
    }
    if (xhr.readyState == 4) {
        console.log (2)
    }
};
console.log(3)

结果是3

猜你喜欢

转载自blog.csdn.net/qq_33712668/article/details/98885110