一、定义
promise是js异步的一种解决方案
1. js为什么要实现异步
js代码首先是单线程执行,即同步执行,正常来讲是在一个线程上有一个执行栈,全局/函数/eval执行上下文根据调用依次压入栈中,执行完后从栈中弹出,先进后出。如果碰到I/O任务,响应会比较慢,这样就会导致以下的问题:
- 造成网页卡死,因为js引擎线程和GUI渲染线程是互斥的,js任务队列没有执行完毕,GUI渲染线程一直被挂起
- 这时候CPU往往是闲着的,浪费了资源
那么为了解决上述问题,就需要js实现异步来解决阻塞问题,将一些需要等待响应的任务作为异步任务,放入任务队列,等待执行栈中的当前任务执行完后,将任务队列推入主线程,依次执行任务队列中的任务。
2. 解决方案是怎样的
3. 还有什么解决方案,它们的区别
4. 自己实现一种方案
什么是单线程语言?
浏览器架构
浏览器是多进程架构,一个tab网页即一个进程,各个tag网页间互不干扰,完全独立。每打开一个tab网页,浏览器就会为该网页分配独立的渲染引擎实例。
渲染引擎(浏览器内核)
渲染引擎即浏览器内核是多线程的,在内核的控制下各线程相互配合以保持同步,这些线程主要包括:
- GUI渲染线程
负责渲染HTML元素,当页面需要重绘repaint/回流reflow时,该线程就会执行。 - JavaScript引擎线程
负责解析js脚本,运行代码,我们常说的V8引擎就是一个js引擎。 - 定时触发器线程
setTimeout、setInterval等待时间结束后把执行函数堆入任务队列中 - 事件触发线程
将click、mouse等交互事件发生后将这些事件放入事件队列中 - 异步http请求线程
处理用户的get、post等请求,等返回结果后将回调函数堆入任务队列
总结
从以上内容可以看出,js代码是被一个js引擎线程来解析执行,即单线程执行,所以说js是单线程语言
为什么是单线程语言
这主要是因为js脚本的作用是处理用户的交互,操作dom,如果做成来多线程的话,一旦dom操作达到临界资源,开启了一个新的线程来执行,而两个线程分别是修改和删除同一个dom,就会出现问题(该问题可以通过锁来解决,但是可能会造成其他的问题,大大增加复杂性)。
如何实现多线程
为了利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,但是子线程完全受主线程控制,且不得操作DOM。所以,这个新标准并没有改变JavaScript单线程的本质。