同步回调与异步回调
同步回调:
理解:立即执行,完全执行了才结束,不会放入回调队列中
例子:数组遍历相关的回调函数/promise的executor函数
异步回调:
理解:不会立即执行,会放入回调队列中将来执行
例子:定时器回调/ajax回调/promise的成功或失败的回调
常见的内置错误
错误的类型
Error:所有错误的父类型
ReferenceError:引用的变量不存在
console.log(a) // ReferenceError:a is not defined
console.log('----') // 没有捕获error,下面的代码不会执行
TypeError:数据类型不正确的错误
let b
console.log(b) // TypeError: Cannot read property 'xxx' of undefined
b = {}
b.xxx // TypeError: b.xxx is not a function
RangeError:数据值不在其所允许的范围内
function fn() {
fn()
}
fn() // RangeError: Maximum call stack size exceeded
SyntaxError:语法错误
const c = """" // SyntaxError: Unexpected string
错误处理
捕获错误:try...catch
抛出错误:throw error
错误对象
message属性:错误相关信息
stack属性:函数调用栈记录信息
promise的理解
抽象表达
promise是js中进行异步编程新的解决方案(旧的是谁?纯回调形式)
具体表达
从语法来说:promise是一个构造函数
从功能来说:promise对象用来封装一个异步操作并可以获取其结果
promise的状态改变
pending变为resolved
pending变为rejected
说明:只有这2种,且一个promise对象只能改变一次
无论变为成功还是失败,都会有一个结果数据
成功的结果数据一般称为value,失败的结果数据一般称为reason
promise的基本流程
![](https://i-blog.csdnimg.cn/blog_migrate/dc0fa247c0161aa50f4afbbfbc49c2bd.png)
promise的基本使用
// 1. 创建一个新的promise对象
const p = new Promise((resolve, reject)=>{ // 执行器函数executor
// 2. 执行异步操作任务
setTimeout(()=>{
const time = Date.now() // 如果当前时间是偶数则成功,否则失败
// 3.1 如果成功了,调用resolve()
if (time %2 === 0) {
resolve('成功', time)
} else {
// 3.2 如果失败了,调用reject()
reject('失败', time)
}
}, 1000);
})
p.then(
value => { // 接收得到成功的value数据 onResolved
console.log('成功', value)
},
reason => { // 接收得到失败的reason数据 onRejected
console.log('失败', reason)
}
)
为什么要用promise
指定回调函数的方式更加ge灵活
a. 旧的:必须则启动异步任务前指定
b. promise:启动异步任务 => 返回promise对象 => 给promise对象绑定回调函数(甚至可以在异步任务结束后指定)
支持链式调用,可以解决回调地狱问题
什么是回调地狱?回调函数嵌套调用,外部回调函数异步执行的结果是嵌套的回调函数执行的条件
回调地狱的缺点?不便于阅读/不便于异常处理
解决方案?promise链式调用
终极解决方案?async/await
promise的API
promise的构造函数:Promise(executor) {}
executor函数:同步执行 (resolve, reject) => {}
resolve函数:内部定义成功时我们调用的函数 value => {}
reject函数:内部定义失败时我们调用的函数 reason => {}
说明:executor会在Promise内部立即同步回调,异步操作在执行器中执行
Promise.prototype.then方法:(onResolved, onRejected) => {}
onResolved函数:成功的回调函数 (value) => {}
onRejected函数:失败的回调函数 (reason) => {}
说明:指定用于得到成功value的成功回调和用于得到失败reason 的失败回调返回一个新的promise对象
Promise.prototype.catch方法:(onRejected) => {}
onRejected函数:失败的回调函数 (reason) => {}
说明:then()的语法糖,相当于:then(undefined, onRejected)
Promise.resolve方法:(value) => {}
value:成功的数据或promise对象
说明:返回一个成功/失败的promise对象
Promise.reject 方法:(reason) => {}
reason:失败的原因
说明:返回一个失败的promise对象
Promise.all方法:(promises) => {}
promises:包含n个promise的数组
说明:返回一个新的promise,只有所有的promise都成功才成功,只要有一个失败了就直接失败
Promise.race方法:(promises) => {}
promises:包含n个promise的数组
说明:返回一个新的promise,第一个完成的promise的结果状态就是最终的结果状态
promise的几个关键问题
如何改变promise的状态?
resolve(value):如果当前是pending就会变为resolved
reject(value):如果当前是pending就会变为rejected
抛出异常:如果当前是pending就会变为rejected
一个promise指定多个成功/失败回调函数,都会调用吗?
当promise改变为对应状态时都会调用
改变promise状态和指定回调函数谁先谁后?
都有可能,正常情况下是先指定回调再改变状态,但也可以先改变状态再指定回调
如何先改状态再指定回调?
在执行器中直接调用resolve()/reject()
延迟更长时间才调哟then()
什么时候才能得到数据?
如果先指定的回调,那当状态发生改变时,回调函数就会调用,得到数据
如果先改变的状态,那当指定回调时,回调函数就会调用,得到数据
promise.then() 返回的新promise的结果状态由什么决定?
简单表达:由then()指定的回调函数执行的结果决定
详细表达:
如果抛出异常,新promise变为rejected,reason为抛出的异常
如果返回的是非promise的任意值,新promise变为resolved,value为返回的值
如果返回的是另一个新promise,此promise的结果就会成为新promise的结果
promise如何串联多个操作任务?
promise的then()返回一个新的promise,可以看成then的链式调用
通过then的链式调用串联多个同步/异步任务
promise异常穿透?
当使用promise的then链式调用时,可以在最后指定失败的回调
前面任何操作出了异常,都会传到最后失败的回调中处理
中断promise链?
当使用promise的then链式调用时,在中间中断,不再调用后面的回调函数
办法:在回调函数中返回一个pending状态的promise对象