这是因为js可以操作Dom,为了避免两段js同时修改一个Dom元素从而发生冲突,所以js的作者采用了单线程机制。
另外,因为浏览器的UI渲染需要渲染Dom元素,所以为了避免和js起冲突,UI渲染和js也是在同一个线程里的;
其中js修改Dom的时候,UI渲染需要暂停。
两者单线程的实质都是为了避免Dom渲染冲突。
根据单线程的原理,一件事没做完之前程序就不往下走,这样势必就会导致等待,等待时间长了次数多了就会造成阻塞。
异步就是解决单线程阻塞问题的一种“无奈”的解决方案。
异步的原理:通俗来讲,就是遇到需要等待的事件,先略过,继续往下走同步的事件,等到到达处理异步事件的时间时,再回头执行异步事件。
异步导致的问题:
1、不按照书写顺序执行,可读性非常差,不利于理解和调试;
2、callback(回调函数)嵌套层级非常多,耦合度相当高,不容易模块化。
问题二:什么是event-loop?什么是异步队列,何时被放入异步队列?
event-loop是事件轮询,JS实现异步的具体解决方案。
event-loop执行原理:
1、所有同步任务都放在主线程中执行,形成一个执行栈;
2、遇到异步任务,暂不执行,将任务插入到异步队列中,它是主线程外专门存放异步任务的队列;
放入异步队列的时机分三种情况:
①没有规定延迟时间,立刻放入异步队列中;
②有延迟时间,到了延迟时间再放入异步队列中;
③类似Ajax,需要等待返回的数据,何时接收到数据何时放入异步队列。
3、等到主进程中的所有同步任务执行完毕时,监听异步队列,轮询执行异步任务。
(轮询是指:只要主线程空了,异步队列中的任务就会进入执行栈,等待执行栈执行完毕,系统再去异步队列中监听读取任务,让异步任务进入执行栈,循环往复)
问题三:是否使用过Jquery的Deferred?
Jquery Deferred是Promise的前身,改变了异步任务必须使用回调函数来书写的方式。
1、先介绍下deferred的使用实例——Jquery1.5前后Ajax写法的变化
Jquery1.5之前,没采用deferred,异步只能采用callback(回调函数)的形式,代码都堆在一块,无法模块化,不便于扩展(对修改开放、对扩展封闭)。
var ajax = $.ajax({ url:\'data.json\', success:function () { console.log(\'success 1\'); console.log(\'success 2\'); console.log(\'success 3\'); }, error:function () { console.log(\'error\'); } }); console.log(ajax); // 返回一个XHR对象