异步
let xhr = new XMLHttpRequest();xhr.open('get', '/temp/list', true); //=> 异步// 此时状态为 1xhr.onreadystatechange = () => {//=> 监听的是 Ajax 状态改变的事件// 设置监听之前有一个状态码,当前后续的状态和设置之前的状态不相同,才会触发这个事件if (xhr.readyState === 2) {console.log(1);}if (xhr.readyState === 4) {console.log(2);}}xhr.send();console.log(3);//=> 输出 3, 1, 2
send 放在前面:
let xhr = new XMLHttpRequest();xhr.open('get', '/temp/list', true); //=> 异步xhr.send(); //=> Ajax 任务开始,是异步的,继续往下走// 此时状态还是 1xhr.onreadystatechange = () => {//=> 监听的是 Ajax 状态改变的事件// 设置监听之前有一个状态码,当前后续的状态和设置之前的状态不相同,才会触发这个事件if (xhr.readyState === 2) {console.log(1);}if (xhr.readyState === 4) {console.log(2);}}console.log(3);//=> 输出 3, 1, 2
同步
let xhr = new XMLHttpRequest();xhr.open('get', '/temp/list', false); //=> 同步// 此时状态为 1xhr.onreadystatechange = () => {//=> 监听的是 Ajax 状态改变的事件if (xhr.readyState === 2) {console.log(1);}if (xhr.readyState === 4) {console.log(2);}}xhr.send(); // Ajax 任务开始,是同步的,完成后才会继续执行console.log(3);//=> 输出 2, 3
当 Ajax 任务开始,由于是同步编程,主任务队列在状态没有变成 4 之前一直被 Ajax 任务占用着,其他事情做不了。当状态码改变为 2,3 时,触发了事件,但是由于主任务队列没有完成,被占着,绑定的方法也无法执行。所以只有状态为 4 的时候执行一次这个方法
send 放在前面:
let xhr = new XMLHttpRequest();xhr.open('get', '/temp/list', true); //=> 同步xhr.send(); //=> Ajax 任务开始,同步,完成后才继续执行// 此时状态还是 4xhr.onreadystatechange = () => {//=> 监听的是 Ajax 状态改变的事件// 设置监听之前有一个状态码,当前后续的状态和设置之前的状态不相同,才会触发这个事件if (xhr.readyState === 2) {console.log(1);}if (xhr.readyState === 4) {console.log(2);}} //=> 不存在状态改变,不会执行console.log(3);//=> 输出 3
