异步

  1. let xhr = new XMLHttpRequest();
  2. xhr.open('get', '/temp/list', true); //=> 异步
  3. // 此时状态为 1
  4. xhr.onreadystatechange = () => {
  5. //=> 监听的是 Ajax 状态改变的事件
  6. // 设置监听之前有一个状态码,当前后续的状态和设置之前的状态不相同,才会触发这个事件
  7. if (xhr.readyState === 2) {
  8. console.log(1);
  9. }
  10. if (xhr.readyState === 4) {
  11. console.log(2);
  12. }
  13. }
  14. xhr.send();
  15. console.log(3);
  16. //=> 输出 3, 1, 2

send 放在前面:

  1. let xhr = new XMLHttpRequest();
  2. xhr.open('get', '/temp/list', true); //=> 异步
  3. xhr.send(); //=> Ajax 任务开始,是异步的,继续往下走
  4. // 此时状态还是 1
  5. xhr.onreadystatechange = () => {
  6. //=> 监听的是 Ajax 状态改变的事件
  7. // 设置监听之前有一个状态码,当前后续的状态和设置之前的状态不相同,才会触发这个事件
  8. if (xhr.readyState === 2) {
  9. console.log(1);
  10. }
  11. if (xhr.readyState === 4) {
  12. console.log(2);
  13. }
  14. }
  15. console.log(3);
  16. //=> 输出 3, 1, 2

同步

  1. let xhr = new XMLHttpRequest();
  2. xhr.open('get', '/temp/list', false); //=> 同步
  3. // 此时状态为 1
  4. xhr.onreadystatechange = () => {
  5. //=> 监听的是 Ajax 状态改变的事件
  6. if (xhr.readyState === 2) {
  7. console.log(1);
  8. }
  9. if (xhr.readyState === 4) {
  10. console.log(2);
  11. }
  12. }
  13. xhr.send(); // Ajax 任务开始,是同步的,完成后才会继续执行
  14. console.log(3);
  15. //=> 输出 2, 3

当 Ajax 任务开始,由于是同步编程,主任务队列在状态没有变成 4 之前一直被 Ajax 任务占用着,其他事情做不了。当状态码改变为 2,3 时,触发了事件,但是由于主任务队列没有完成,被占着,绑定的方法也无法执行。所以只有状态为 4 的时候执行一次这个方法

send 放在前面:

  1. let xhr = new XMLHttpRequest();
  2. xhr.open('get', '/temp/list', true); //=> 同步
  3. xhr.send(); //=> Ajax 任务开始,同步,完成后才继续执行
  4. // 此时状态还是 4
  5. xhr.onreadystatechange = () => {
  6. //=> 监听的是 Ajax 状态改变的事件
  7. // 设置监听之前有一个状态码,当前后续的状态和设置之前的状态不相同,才会触发这个事件
  8. if (xhr.readyState === 2) {
  9. console.log(1);
  10. }
  11. if (xhr.readyState === 4) {
  12. console.log(2);
  13. }
  14. } //=> 不存在状态改变,不会执行
  15. console.log(3);
  16. //=> 输出 3