异步的底层原理
js中的异步的实现的原理是单线程加事件队列,js的代码执行是单线程的,所谓的单线程的含义是js的代码是从上往下按顺序依次执行的,一定是上一行代码执行完再执行下一行代码。事件队列可以认为是一个容器,这个容器中存储一些回调函数。这些回调函数只有在js代码全部执行完成之后,才有可能会去调用,因为js是单线程的,一次只能做一件事。
可以用setTimeout函数模拟一下:
setTimeout(function(){ console.log(‘定时函数代码执行了‘) },2000) console.log(‘正常代码执行了‘)
解读一下:
js代码是从上往下执行,遇到setTimeout函数,是把里面的函数放在事件队列里面,接着向下执行,再等到js空闲的情况下,会去事件队列中看一下,有没有方法达到触发条件
所以执行的结果是:
setTimeout(function(){ console.log(‘定时函数代码执行了‘) },2000) console.log(‘正常代码执行了‘) //正常代码执行了 //定时函数代码执行了
大家肯定心存疑惑,总觉得是巧合,下面的例子就可以充分说明了我的观点
setTimeout(function(){ console.log(‘定时函数代码执行了‘) },2000) var str = ‘‘ for(var i = 0;i < 10000000;i ++){ str += i } console.log(‘正常代码执行了‘)
在打印之前,添加了for循环,但是结果仍然是:
//正常代码执行了 //定时函数代码执行了
再在原来代码上稍微改进一点
setTimeout(function(){ console.log(‘定时函数代码执行了‘) },2000) var str = ‘‘ for(var i = 0;i < 10000000;i ++){ str += i } console.log(‘正常代码执行了‘) var str = ‘‘ for(var i = 0;i < 10000000;i ++){ str += i }
最后得到结果是:
先出现:正常代码执行了
再出现:定时函数代码执行了
最后再来看一下ajax代码:
var xhr = new XMLHttpRequest() //1.创建对象 xhr.open(‘get‘,‘url?xxx‘+xxx,true) //2.准备发送 xhr.send(null) //3.执行发送 xhr.onreadystatechange = function (){ //4.回调函数 if(xhr.readyState == 4){ if(xhr.status == 200){ var result = xhr.responseText console.log(result) } } }
上图js执行流程
1·········>2·········>3·········>4
当执行到第3步的时候
js请求浏览器进行网络数据的请求
因为js是单线程的,但是浏览器不是单线程的。
原文:https://www.cnblogs.com/xufeng1994/p/10431048.html