基础准备
实例对象与函数对象
实例对象:new 生成的对象,称为实例对象,简称对象
函数对象:将函数作为对象使用时,称为函数对象
1 | function Fn(){} |
区分对象与函数: 后面跟括号()
的是函数,跟点.
的是对象
两种类型回调函数
回调函数:自定义的函数;不亲自调用;最终会执行
通常回调函数使用箭头函数(便于利用this指向)
同步回调
理解:立即执行,完全执行完才结束,不会放到回调队列中
例子:数组遍历相关回调 / Promise的excutor函数
异步回调
理解:不会立即执行,会放入回调队列
例子:定时器回调 / ajax回调 / Promise的成功 | 失败回调
JS的error处理
错误类型
Error:所有类型错误
ReferenceError:引用的变量不存在
TypeError:数据类型错误
RangeError:数据值不在其所允许的范围内
SyntaxError:语法错误
1 | console.log(a) // ReferenceError a不存在 |
错误处理
正常流当中,出错后,程序无法继续向下执行
(1)捕获错误: 捕获程序中出现的错误,并主动对该错误进行处理
1 | try{ |
error是一个错误对象
包括message、stack属性,默认显示的是stack属性
(2)抛出错误: 主动抛出错误,由外部决定如何处理该错误
1 | function something() { |
Promise的理解和使用
promise是什么
Promise是JS中进行异步编程的解决方案,从语法上老说,Promise是一个构造函数,从功能上来说,Promise用来封装一个异步操作并可以获取其结果
promise状态改变
Promise有三种状态:pending
、resolved
、rejected
状态改变只有两种: pending变为resolved / rejected
一个promise对象只能改变一次,成功的结果数据一般称为value,失败的结果一般称为reason
promise基本流程
1 | const p = new Promise((resolve, reject)=>{ // promise执行器默认两个参数 |
为什么用promise
(1)指定回调函数方式更灵活
旧方法:必须在启动异步任务前指定
Promise:启动异步任务 --> 返回promise对象 --> 给promise对象绑定回调函数(也可以在异步任务开始前就绑定)
(2)支持链式调用,解决回调地狱问题
回调地狱不利于阅读及异常处理
终极方案:async / await
如何使用promise
(1)Promise构造函数:new Promise ( excutor ) { }
excutor函数:同步执行(resolve,reject)=>{}
resolve函数:内部定义成功时调用的函数 value => {}
reject函数:内部定义成功时调用的函数 reason => {}
excutor会在Promise内部立即执行(同步回调),异步操作在该执行器中执行
(2)Promise.prototype.then方法:Promise对象.then((onResolved, onRejected)=>{})
onResolved函数:成功的回调函数(value)=>{}
onRejected函数:失败的回调函数(reason)=>{}
then方法用于得到成功value的成功回调和失败reason的失败回调,返回一个新的promise对象
(3)Promise.prototype.catch方法:Promise对象.catch((onRejected)=>{})
then()的语法糖,相当于then(undefined, onRejected)
(4)Promise.resolve方法:Promise.resolve()
value:成功的数据或promise对象
返回一个成功/失败的promise对象
(5)Promise.reject方法:Promise.reject()
reason:失败的原因
返回一个失败的promise对象
(6)Promise.all方法:Promise.all(promises)
promises:包含n个promise的数组
返回一个新的promise,只有所有的promise都成功才成功,只要有一个失败则失败
若都成功,则.then()成功值为所有成功值组成的数组,且数组元素顺序与promise数组顺序一致,与执行完成先后无关
若有失败,则为第一个失败的结果
(7)Promise.race方法:Promise.race(promises)
promises:包含n个promise的数组
以数组内元素的顺序开启promise,以实际执行完毕的先后返回整体的结果
返回一个新的promise,第一个完成的promise的结果是最终结果
Promise关键问题
(1)promise中如果抛出异常,则状态改变为rejected,reason为抛出的异常
1 | const p = new Promise((resolve, reject)=>{ |
(2)一个promise指定多个成功/失败回调函数,则都会调用
1 | const p = new Promise((resolve, reject)=>{ |
(3)promsie状态改变和指定回调的先后顺序不是确定的
1 | // 先指定回调,后改变状态 |
(4)then当中的回调函数是异步执行的
1 | new Promise((resolve, reject)=>{ |
(5)promise.then()返回的新promise的状态及结果由什么决定
由then()指定的回调函数的执行的结果决定
具体来说:
①如果抛出异常,则为rejected,reason为抛出的异常
②如果返回(return)非promise的任意值,则为resolved,value为返回的值
③如果返回的是另一个promise,则看该pormise的执行结果,以该结果为结果
④如果没有上述情况,则为resolved,value为undefined
1 | new Promise((resolve, reject) => { |
(6)promise串联多个操作任务,每个then都要等上一个完成后才执行
1 | new Promise((resolve, reject) => { |
(7)promise异常传透
当使用promise链式调用时,可以在最后处理失败,是因为未指定失败回调时,默认做了处理,将错误传递下去
1 | new Promise((resolve, reject) => { |
(8)中断promise链
在promise链上返回一个pending状态的promise对象,即可中断promise链
1 | new Promise((resolve, reject) => { |
async与await
async函数
async后面通常跟函数,返回值为一个promise对象
该promise对象的结果由async函数执行的结果确定
1 | async function fn1() { |
await表达式
await后面跟表达式(能得到一个值的代码)
若表达式为promise,得到promise成功的value
若promise失败,会报错,需要try...catch
处理,获得失败的promise的值
若表达式不是promise,得到的结果就是它本身
JS异步之宏队列与微队列
宏队列:定时器回调/ajax回调/DOM事件回调
微队列:promise回调/MutationObserver回调
优先级:同步>微队列>宏队列
每次取出宏队列的任务执行前,都要将微队列的任务全部取出执行
参考视频: