JS引擎的执行机制:(单线程和event Loop的执行机制)
参考:
https://segmentfault.com/a/1190000012806637
http://www.ruanyifeng.com/blog/2013/10/event_loop.html
注意:
Worker API可以实现多线程,但是JavaScript本身始终是单线程的
1.什么是even Loop的执行机制
简单的来说,就是在程序中,设置两个线程:
一个线程,负责程序本身的运行,称为主线程
一个线程负责主线程与其他线程的操作(主要是各种IO操作),称为event Loop线程(也叫消息线程)
执行原理:
1.主程序遇到I/O的时候,交给event Loop执行(自己则继续往后面执行)
2.等到Event LOop线程执行完毕之后,返回给主线程
3.主线程触发,相应的回调操作
4.执行完毕
结论:
这样,就解决了单线程的问题
这种运行方式,叫做异步模式或非阻塞模式(node JS 也是这样的)
2.JS是单线程的历史原因
为了简单
队列,并发,进程和线程--在浏览器中(怎么简单,怎么来)
3.为啥要使用异步:
设计到了JS的执行顺序
自上而下的 (有一段代码太大,后面就会卡死)
这个就叫做阻塞,于是就有了异步的解决方案.
4.异步的执行案例:
代码:
对于上面案例的分析:
开始的console-->结尾的console--->定时器
再看一眼执行的顺序:
1.判断代码是同步的还是异步的
同步的,就进入主线程
异步的,就进入event tablt
2.异步的任务在event table 里面注册函数,当满足触发条件的时候进入event queque(就是事件队列)
3.当主线程空闲的时候,就去event queque里面查看是否有可执行的异步任务
如果,有 就推入到主线程里面
于是,上面的就可以解释了
setTimeout() 是一个异步的任务(空闲的时间才会执行他)
===================================================================
另一个案例:
代码:
在此之前,我们需要了解一下ES6的一些语法
ES6(碰到一个,学一个)
参考:
http://es6.ruanyifeng.com/#docs/promise
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise
关于promise(承诺)
1.他是一个容器(对象方式的容器)
2.容器里面存放的是某个异步操作(未来才会结束的事件)
3.容器里面的内容有什么特点呢??
1.对象的状态不受外部的影响
那他有哪几种会状态呢??
pending(进行中)、fulfilled(已成功)和rejected(已失败)
只有异步操作的结果,可以改变状态
2.一旦状态改变就不会再变,任何时候都是这个结果
什么是状态改变:
状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected
为了方便,我们把
resolved(已定型)统一只指fulfilled
4.promise的语法结构:
Promise()构造函数,创建promise对象
代码:
new Promise(function(resolve, reject){ //必须写上回调函数,否则会报错的
//参数,resolve和reject ,由 JavaScript 引擎提供,不用自己部署。
}).then(function(value){
//成功的返回值
静态方法 Promise.resolve返回一个promise对象,这个promise对象是被解析后(resolved)的
},function(error){
//失败的返回值
})
关于这两个参数:(貌似都是返回一个对象啊)
1.Promise.resolve()方法
静态方法 Promise.resolve返回一个promise对象,这个promise对象是被解析后(resolved)的
语法:
Promise.resolve(value);
Promise.resolve(promise);
Promise.resolve(thenable);
2.Promise.reject(reason)方法返回一个用reason拒绝的Promise\
扩展结束,我们来分析这个案例:
执行结果:
执行for循环之前-->代码执行结束了--->执行了then函数了--->定时器开始了
结构分析:
1.由上到下执行
setTimeout() 放在全局的异步执行队列中(宏任务)
2.创建promise对象
回调函数立即执行,打印执行for循环之前
then 是异步的,存在当前的异步执行队列中(微任务)
3.全局
代码执行结束了
4.返回到那个内部的异步 Event Loop里面执行
执行then函数
5,执行全局的异步队列中的函数
执行完主程序之后
先看看微任务有未执行的吗,如果有,就先执行他-=--这不是开小灶吗
之后执行红任务
疑惑:
就两个线程
这个多了一个,算是嵌套吗????
还有一个坑:
代码:
setTimeout(
function(){
console.log('执行了')
},3000 )
其实,不是3s之后执行
而是,3s之后,被推入Event Loop执行队列中
主程序有空闲,就来执行该程序
执行的条件
所以只有满足 (1)3秒后 (2)主线程空闲,同时满足时,才会3秒后执行该函数