事件循环;控制台异步;Promise;生成器;async await;
书摘&心得
1、异步:现在与将来
- 控制台是异步的,是宿主环境提供的。
- console.log的改变是控制台I/O的异步化造成的
- 解决方案1:使用debugger
- 解决方案2:把对象序列化到一个字符串中JSON.stringify()
- 事件循环
- javaScript寄宿在宿主(浏览器)上
- 宿主浏览器提供一种机制——事件循环,来执行多个块。
- 事件循环的每一轮称为一个tick
- 用户交互、I/O、定时器会向事件队列中插入事件
- 同步操作会阻塞用户交互,锁定浏览器UI
- javaScript引擎按需执行代码片段,宿主决定什么时候执行
- setTimeout精度不高:定时器只是在指定时间后把回调挂入事件循环队列而已。【中卷143】
- ES6本质上改变了由哪里管理事件循环
- 并发
- 看起来是同时工作,实际上是事件在交替执行
- 门闩协调,保证只有第一名生效
- 不霸占事件循环队列?搜索树大数据性能优化终极方案【155】
- 可使用setTimeout(…0)进行异步调度——把这个函数插入到当前事件循环的结尾处。
- 把自身分隔为更小的块
任务队列 job queue【156】
回调函数包裹了程序的延续【162】
- 回调相当于把函数交给第三方实现
- 回调的缺陷
- 与大脑的思维方式不相符
- 控制反转,存在信任问题
-
3、Promise
反转再反转
- 不由第三方执行回调,而是第三方提供时机,我自己根据时机决定代码的下一步
- Promise构造函数
- (fn),fn的参数是resolve函数和reject函数
- 创建出来的就是promise对象
- 传入一个executor回调函数
- executor可获得Promise内部的resolve和reject
- 可在回调函数中执行resolve()或reject()
- promise.then()
- (onfulfilled,onreject),onfulfilled的参数是value,onreject的参数是reason
- 有两个参数,onfulfilled在promise对象resolved时执行,onrejected在promise对象rejected时执行。
- promise.then本身会创建一个新的promise对象
- (onfulfilled,onreject),onfulfilled的参数是value,onreject的参数是reason
- promise承诺,未来发生,一旦许下不可变。
- 未来值:关注promise的决议函数的返回值
- 完成事件:关注promise的决议函数本身
- 任何具有then方法的对象和函数即promise
使用Promise.resolve()把函数封装一层调用then,能更好地建立信任
4、生成器generator
生成器是*fn,迭代器对象是g=fn()
- 生成器是生产者,而迭代器是快递员:送入原料给生成器、输出产品给我们
- 控制生成器需要调用迭代器对象g,g.next()可以才可以启动生成器
- 消息传递是双向的
- 迭代器对象g.next()可以获取yield时生成器的返回值
- 迭代器对象g.next()也可以接收参数,向生成器注入参数代替暂停处的yield
- 提问(next)与回答(yield/return)
- 让异步的代码看起来像同步一样【中卷 250 读三遍】
- 请求数据的时候遇到yeild暂停
- 通过迭代器将请求到的数据传回生成器
- 异步被抽象出去了,代码变得符合人脑逻辑,一团乱麻的回调bye bye
- 完美世界:generator+promise(有点像dva的模式?)
- yield出来一个promise对象
- 在promise对象中恢复生成器
- async await相当于把完美世界写进规范(好比js和jquery的关系?)
- 生成器委托
- 在一个生成器中使用另一个生成器yield *fn()
- 形实转换程序【中卷 274】
- javaScript中的thunk是指一个用于调用另外一个函数的函数,没有任何参数