异步问题
嵌套层次很深,难以维护 – 回调地狱
无法正常使用return 和 throw
无法正常检索堆栈信息
多个回调之间难以建立联系
Promise
promise是一个代理对象,它和原先要处理的操作并无关系
promise通过引入一个回调,避免更多的回调
promise三个状态
promise状态发生改变,就会出发.then()里面的响应函数处理后续步骤
promise状态一经改变,不会再变。
pending [待定]初始状态
fulfilled [实现]操作成功
rejected [被否决]操作失败
详看博主的另一篇文章
.then
.then() 接受两个函数作为参数,分别代表fulfilled 和 rejected
.then()返回一个新的Promise实例,所以它可以链式调用
当前面的Promise状态改变时,.then()根据其最终状态,选择特定的状态响应函数执行
状态响应函数可以返回新的Promise,或其他值
如果返回新的Promise,那么下一级.then()会在新Promise状态改变之后执行
如果返回其他任何值,则会立刻执行下一级.then()
错误处理
Promise会自动捕获内部异常,并交给rejected响应函数处理。
错误处理的两种做法:
reject(‘错误信息’).then(null, message => {})
throw new Error(‘错误信息’).catch(message => {})
推荐使用第二种,更加清晰好读,并且可以捕获前面的错误。
错误和then连用
强烈建议在所有队列最后都加上.catch(),以避免漏掉错误处理造成意想不到的问题
Promise进阶
Promise.all()
批量执行: Promise.all([p1,p2,p3,…])用于将多个Promise实例,包装成一个新的Promise实例。
返回的实例就是普通Promise
它接受一个数组作为参数
数组里可以是Promise对象,也可以是别的值,只有Promise会等待状态改变
当所有子Promise都完成,该Promise完成,返回值是全部值的数组
有任何一个失败,该Promise失败,返回值是第一个失败的子Promise的结果
Promise.all() 和 .map()连用
实现队列
有时候我们不希望所有动作一起发生,而是按照一定顺序,逐个进行。
Promise.resolve()
返回一个 fulfilled 的Promise实例,或原始Promise实例。
参数为空,返回一个状态为fulfilled的Promise实例
参数是一个跟Promise无关的值,同上,不过fulfuilled响应函数会得到这个参数
参数为Promise实例,则返回该实例,不做任何修改
参数为thenable,立刻执行它的.then()
Promise.reject()
返回一个rejected的Promise实例。
Promise.reject() 不认 thenable
Promise.race()
类似Promise.all(),区别在于它有任意一个完成就算完成。
把异步操作和定时器放在一起
如果定时器先触发,就认为超时,告知用户
把回调包装成Promise
把回调包装成Promise最为常见。它有两个显而易见的好处:
可读性更好