promise
函数对象、实例对象
1.函数对象: 将函数作为对象使用时, 简称为函数对象。
2.实例对象: new 构造函数或类产生的对象, 我们称之为实例对象。
函数有个属性name指的是函数的名字: function Person(){} Person.name //Person
回调
我们定义的,我们没有调用,最终执行了。
1.同步的回调函数:
理解: 立即在主线程上执行, 不会放入回调队列中。
例子: 数组遍历相关的回调函数
2.异步的回调函数:
理解: 不会立即执行, 会放入回调队列中以后执行
例子: 定时器回调 / ajax回调
错误
1. 错误的类型
2. 错误处理
3. 错误对象
Promise是什么?
1.抽象表达:
2.具体表达:
用法
1.Promise不是回调,是一个内置的构造函数,是程序员自己使用new调用的。
2.new Promise的时候,要传入一个同步的回调函数,会立即在主线程上执行,它被称为executor函数(executor函数)
3.每一个Promise实例都有3种状态:初始化(pending)、成功(fulfilled)、失败(rejected)
4.每一个Promise实例在刚被new出来的那一刻,状态都是初始化(pending)
5.executor函数会接收到2个参数,它们都是函数,分别用形参:resolve、reject接收
1.调用resolve函数会:
(1).让Promise实例状态变为成功(fulfilled)
(2).可以指定成功的value。
2.调用reject函数会:
(1).让Promise实例状态变为失败(rejected)
(2).可以指定失败的reason。
1. 重要语法
new Promise(executor)构造函数
Promise.prototype.then方法
2. 基本编码流程
1.创建Promise的实例对象(pending状态), 传入executor函数
2.在executor中启动异步任务(定时器、ajax请求)
3.根据异步任务的结果,做不同处理:
3.1 如果异步任务成功了:
我们调用resolve(value), 让Promise实例对象状态变为成功(fulfilled),同时指定成功的value
3.2 如果异步任务失败了:
我们调用reject(reason), 让Promise实例对象状态变为失败(rejected),同时指定失败的reason
4.通过then方法为Promise的实例指定成功、失败的回调函数,来获取成功的value、失败的reason
注意:then方法所指定的:成功的回调、失败的回调,都是异步的回调。
3. 关于状态的注意点:
1.三个状态:
pending: 未确定的------初始状态
fulfilled: 成功的------调用resolve()后的状态
rejected: 失败的-------调用reject()后的状态
2.两种状态改变
pending ==> fulfilled
pending ==> rejected
3.状态只能改变一次!!
4.一个promise指定多个成功/失败回调函数, 都会调用吗?是的,都会被推入队列随后调用
API
finally() 方法返回一个Promise。在promise结束时,无论结果是fulfilled或者是rejected,都会执行指定的回调函数。这为在Promise是否成功完成后都需要执行的代码提供了一种方式。
这避免了同样的语句需要在then()和catch()中各写一次的情况。
2. 改变Promise实例的状态和指定回调函数谁先谁后?
1.都有可能, 正常情况下是先指定回调再改变状态, 但也可以先改状态再指定回调
2.如何先改状态再指定回调?
延迟一会再调用then()
3.Promise实例什么时候才能得到数据?
如果先指定的回调(回调会被暂存到自身), 那当状态发生改变时, 回调函数就会拿出来调用, 得到数据
如果先改变的状态(状态也会被暂存到自身), 那当指定回调时, 回调函数就会立即调用, 得到数据
Promise实例.then()返回的是一个【新的Promise实例】,它的值和状态由什么决定?
1.简单表达: 由then()所指定的回调函数执行的结果决定
2.详细表达:
(1)如果then所指定的回调返回的是非Promise值a:
那么【新Promise实例】状态为:成功(fulfilled), 成功的value为a
(2)如果then所指定的回调返回的是一个Promise实例p:
那么【新Promise实例】的状态、值,都与p一致
(3)如果then所指定的回调抛出异常:
那么【新Promise实例】状态为rejected, reason为抛出的那个异常
中断promise链:
(1)当使用promise的then链式调用时, 在中间中断, 不再调用后面的回调函数。
(2)办法: 在失败的回调函数中返回一个pendding状态的Promise实例。
promise错误穿透:
(1)当使用promise的then链式调用时, 可以在最后用catch指定一个失败的回调,
(2)前面任何操作出了错误, 都会传到最后失败的回调中处理了
备注:如果不存在then的链式调用,就不需要考虑then的错误穿透。
Promise的优势
async与await
1. async修饰的函数
函数的返回值为promise对象
Promise实例的结果由async函数执行的返回值决定
2. await表达式
await右侧的表达式一般为Promise实例对象, 但也可以是其它的值
(1).如果表达式是Promise实例对象, await后的返回值是promise成功的值
(2).如果表达式是其它值, 直接将此值作为await的返回值
3. 注意:
await必须写在async函数中, 但async函数中可以没有await
如果await的Promise实例对象失败了, 就会抛出异常, 需要通过try...catch来捕获处理
await的原理
若我们使用async配合await这种写法:
1.表面上不出现任何的回调函数
2.但实际上底层把我们写的代码进行了加工,把回调函数“还原”回来了。
3.最终运行的代码是依然有回调的,只是程序员没有看见。
宏队列与微队列
宏队列:[宏任务1,宏任务2.....]
微队列:[微任务1,微任务2.....]
规则:每次要执行宏队列里的一个任务之前,先看微队列里是否有待执行的微任务
1.如果有,先执行微任务
2.如果没有,按照宏队列里任务的顺序,依次执行