所谓单线程,就是只一次只能完成一件任务。若是有多个任务,就必须排队,前面一个任务完成,在执行后面一个任务,以次类推。javascript
js执行分为同步和异步,其中异步来自于浏览器提供的异步队列,在浏览器中分为两个任务队列,一个是主任务队列【同步编程】,一个是等待任务队列【异步编程】java
一个浏览器一般由一下几个常住的线程编程
setTimeout
,setInterval
注意:渲染线程和js引擎线程是不能同时进行的。渲染线程在执行任务的时候,js引擎线程会被挂起。由于js能够操做DOM,若在渲染中js处理了DOM,浏览器可能就不知所措了浏览器
虽然JavaScript是单线程的,但是浏览器内部不是单线程的。一些I/O操做、定时器的计时和事件监听(click, keydown...)等都是由浏览器提供的其余线程来完成的。服务器
"同步模式"就是上一段的模式,后一个任务等待前一个任务结束,而后再执行,程序的执行顺序与任务的排列顺序是一致的、同步的;"异步模式"则彻底不一样,每个任务有一个或多个回调函数(callback),前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前一个任务结束就执行,因此程序的执行顺序与任务的排列顺序是不一致的、异步的。多线程
"异步模式"很是重要。在浏览器端,耗时很长的操做都应该异步执行,避免浏览器失去响应,最好的例子就是Ajax操做。在服务器端,"异步模式"甚至是惟一的模式,由于执行环境是单线程的,若是容许同步执行全部http请求,服务器性能会急剧降低,很快就会失去响应。异步
console.log(1) function fn(){ console.log(2) } fn() console.log(3)
上面代码输入1 2 3 ,由于js是单线程的,代码由上而下依次执行async
js中异步编程
回调函数函数
上面这4中都是属于异步的
console.log(1) setTimeout(()=>{ console.log(2) }) console.log(3)
上面代码执行会输出,1 3 2 ,由于
setTimeout
是异步的,js会将setTimeout
放到异步队列,等待同步队列所有执行完毕,在执行异步队列
js中有两类任务队列:宏任务队列和微任务队列。宏任务队列能够有多个,微任务队列只有一个
setTimeout(_ => console.log(4)) new Promise(resolve => { resolve() console.log(1) }).then(_ => { console.log(3) }) console.log(2)
上面代码中,setTimeout就是做为宏任务来存在的,而Promise.then则是具备表明性的微任务
全部会进入的异步都是指的事件回调中的那部分代码
也就是说
new Promise
在实例化的过程当中所执行的代码都是同步进行的,而then
中注册的回调才是异步执行的。
在同步代码执行完成后才回去检查是否有异步任务完成,并执行对应的回调,而微任务又会在宏任务以前执行。因此就获得了上面的输出1 2 3 4