到底什么是Event Loop呢?
JavaScript到底是什么?答案像是这样:“Javascript是一个单线程、非阻塞、异步、解释性脚本语言”,只有一个线程,同一时间只能做一件事。
以下是Javascript运行环境示意图,堆记录了内存的分配、然后调用栈。
栈里面很慢的东西都叫阻塞
var foo = $.getSync('//foo.com');
var bar = $.getSync('//bar.com');
var qux = $.getSync('//qux.com');
console.log(foo);
console.log(bar);
console.log(qux);
以上是一段jquery的伪代码,它们分别发送网络请求,如果请求中遇到网络过慢或者其它问题,都会导致后面的代码阻塞。
浏览器需要渲染DOM
JS可以修改DOM结构
JS执行的时候,浏览器DOM渲染会暂停
两段JS也不能同时执行(都修改了DOM就冲突了)
webworker支持多线程,但是不能访问DOM
Javascript只有一个线程就是避免DOM渲染的冲突,异步是单线程的解决方案。
// setTimeout也是异步的一种解决方案
异步解决方案存在的问题:
没有按照书写方式执行,可读性差(比如 setTimeout )
callback中不容易模块化
事件轮询、事件循环(event-loop)
事件轮询,JS实现异步的具体解决方案
同步代码,直接执行
异步函数先放在异步队列中
待同步函数执行完毕,轮询执行异步队列的函数
无法改变JS异步和单线程的本质
只能从写法上杜绝callback这种形式
它是一种语法糖形式、但是解耦了代码
很好的体现:开放封闭原则(对拓展开放,对修改封闭)
Promise实例必须实现then这个方法
then() 必须是两个参数
then() 返回的必须是一个Promise实例
then只是将callback拆分了
async/await 是最直接的同步写法
使用await,函数必须使用async标识
await后面跟的是一个Promise实例
需要引用 babel-polyfill
使用了Promise,并没有和Promise冲突
完全是同步的写法,再也没有回调函数
但是:改变不了JS单线程、异步的本质
jquery Deferred
Promise
Asyns/Await
Generator
Generator 原理比较复杂、不是异步的直接替代方式、有更好的简洁的解决方案 asyns/await