promise
2.1promise是什么
抽象表达:是js中进行异步编程的新的解决方案
具体表达:从语法上看,promise是一个构造函数;从功能上看,promise队形用于封装一个异步操作,并可以获取其结果
2.2promise 状态
pending 变成resolved
pending 变成rejected
说明:只有这2种,且一个promise对象只能改变一次
无论变为成功还是失败,都会有一个结果数据
成功的结果数据一般称为value 失败的结果数据一般称为reason
promise优势
如何使用promise
race()看谁先完成
promise 小问题
先回调再改变状态
先改状态后指定回调函数
promise 不论失败还是成功的回调函数都是异步执行
没有写return 的话 第二个then返回undefined
串联多个操作:异步不能像蓝色这样写不对,得通过new promise
传透是一层一层传过来
让then不执行
手写promise
1.定义整体结构
promise中的resolve
注意:回调函数需要异步执行,所以需要放入setTimeout中;
且状态只能改变一次
reject
执行器抛出异常,promise要变为失败状态
then方法实现:需要判断状态,依次考虑;注意this指定问题
then的简单实现
返回一个新的promise对象,需要判断回调函数的值
返回一个promise,return的promise结果就是这个promise结果
简写形式,注意div.οnclick=fn 如果带括号会立刻执行
简写形式为:
如果是rejected状态
重构代码
定义指定回调函数处理
最终版then方法
throw左边不能有return
实现异常传透的关键一步
catch()
then 函数总结
resolve 和reject 实现
原生resolve返回
指定数组长度 new Array(promise.length),要判断是不是成功,成功的话将所有成功的value输出
promise输出顺序与all后面顺序有关,和声明顺序无关;所以以下输出 5 2 3
race问题:尽管是遍历,但只会改变一次,因为第一次的时候已经从pending状态变为rejected或者resolved。所以之后就不会发生改变。
race 是看谁最先完成。也可以直接传一个数字,以下结果因为p4是1秒之后执行,所以输出7
处理传入非promise对象,将参数放入 promise.resolve§中
延迟返回一个promise对象
类中如下图的方法就定义在原型上
类中如下图的方法给类对象添加
async和await
加上async的函数返回值是promise对象
用了await必须用async
try catch得到失败的结果
js异步之宏队列与微队列
主要有三大部分:js引擎 队列 管理模块
js引擎:堆中放对象,栈中放函数
队列分为宏队列和微队列
宏队列:dom ajax 定时器回调
微队列:promise
执行先后问题:微队列先执行
js执行过程:先执行完所有同步代码,再执行队列中的代码。优先执行微队列的回调函数
说明
注意最后一句话 每次准备取出第一个宏任务之前都需要将所有的微任务一个一个取出执行
面试题
输出: 3 2 4 1
输出:2 5 3 4 1
then执行,既要有函数 又要改变状态
微队列【3】因为后面的then没有状态改变,所以4并没有放入微队列中
此时宏队列的值为【1】
同步任务执行后,开始取微队列任务执行,3输出,状态改变,【4】放入微队列中
执行 微队列任务 输出4
执行宏队列任务输出 1
输出:3 7 4 1 2 5
宏队列 【5】
resolve(1)执行,将p的状态改变为resolved。然后resolve(2)执行,改变外面first的状态 然后会将p.then放入微队列中
微队列 【1,2】
注意 resolve(6)不会有效果
因为已经状态改变了
输出:1 7 2 8 4 6 5 0
宏【0】
.then(()=>)里面的内容会放到微队列中;下面的.then()不会放到微队列中因为上面的函数还没有执行,不知道状态的改变。下面new promise中同步输出7,执行resolve(),将then()函数中的内容放入微队列中。
微队列【2,8】
取出输出2的回调函数,接着又new了一个promise先输出3,执行resolve,并将输出为4的回调函数放入队列
微队列 【8,4】
4还没有执行,所以5的回调函数不会放入队列中。但6中的状态发生了改变,所以需要把6放入到队列中
微队列 【8 4 6】
取出微队列 8 执行,输出8
取出微队列4 执行,输出4,并将5放入微队列中
微队列【6 5】
取出6执行,输出6
取出5执行,输出5
取出0执行,输出0