JS中的同步异步编程

 
  首先我们先看看同步与异步的定义,及浏览器的执行机制,方便我们更好地理解同步异步编程。
  
  浏览器是多线程的,JS是单线程的(浏览器只分配一个线程来执行JS)
 
  进程大线程小:一个进程中包含多个线程,例如在浏览器中打开一个HTML页面就占用了一个进程,加载页面的时候,浏览器分配一个线程去计算DOM树,分配其它的线程去加载对应的资源文件...再分配一个线程去自上而下执行JS

  同步:在一个线程上(主栈/主任务队列)同一个时间只能做一件事情,当前事情完成才能进行下一个事情(先把一个任务进栈执行,执行完成,在把下一个任务进栈,上一个任务出栈...)

  异步:在主栈中执行一个任务,但是发现这个任务是一个异步的操作,我们会把它移除主栈,放到等待任务队列中(此时浏览器会分配其它线程监听异步任务是否到达指定的执行时间),如果主栈执行完成,监听者会把到达时间的异步任务重新放到主栈中执行...
    
  [宏任务:macro task]
        - 定时器
        - 事件绑定
        - ajax
        - 回调函数
        - Node中fs可以进行异步的I/O操作
  [微任务:micro task]
        - Promise(async/await)  => Promise并不是完全的同步,当在Excutor中执行resolve或者reject的时候,此时是异步操作,会先执行then/catch等,当主栈完成后,才会再去调用resolve/reject把存放的方法执行
        - process.nextTick (node中实现的api)
 

  执行顺序优先级:SYNC => MICRO => MACRO

  所有JS中的异步编程仅仅是根据某些机制来管控任务的执行顺序,不存在同时执行两个任务这一说法

我们用ajax来看看js的同步与异步的执行顺序和机制,AJAX任务开始:SEND,AJAX任务结束:状态为4
let xhr = new XMLHttpRequest();
xhr.open('GET', 'xxx.txt', false);
// 放到等待区的时候,此时状态是1
xhr.onreadystatechange = () => {
    console.log(xhr.readyState);//=>4
};
xhr.send();

// 状态为4的时候主栈空闲
 let xhr = new XMLHttpRequest();
 xhr.open('GET', 'xxx.txt', false);
 xhr.send();
// 状态已经为4了
 xhr.onreadystatechange = () => {//=>状态改变才会触发,放到等待区的时候状态已经为4了,不会在改变了,所以不会执行这个方法(啥都不会输出)
     console.log(xhr.readyState);
 };
 let xhr = new XMLHttpRequest();
 xhr.open('GET', 'xxx.txt');
 xhr.send();//=>异步操作:执行SEND后,有一个线程是去请求数据,主栈会空闲下来
// 放等待区之前状态是1
 xhr.onreadystatechange = () => {
     console.log(xhr.readyState);//=> 2 3 4
 };
// 主栈又空闲了
// 状态为2  把函数执行
// 状态为3  把函数执行
// 状态为4  把函数执行

猜你喜欢

转载自www.cnblogs.com/jiajialove/p/11978644.html