Promise
实例对象和函数对象的区别
- 实例对象:
new
函数产生的对象,称实例对象简称对象 - 函数对象:将函数作为对象使用时,简称函数对象
两种类型的回调函数
同步回调:立即执行,执行完了才结束,不会放入回调函数队列
异步回调:不会立即执行,会放入回调函数队列中将来执行
JS的error
处理
错误类型
Error
:所有错误的父类型ReferenceError
:引用的变量不存在TypeError
:数据类型不正确RangeError
:数据值不再其允许的范围内SyntaxError
:语法错误
错误对象
message
属性:错误相关信息
stack
属性:函数调用栈记录信息
错误处理
- 捕获错误:
try ... catch
- 抛出错误:
throw error
//捕获错误
try {
var a = null;
a.xxx
} catch (error){
console.log(error.message)
console.log(error.stack)
}
//抛出错误
function something() {
if(Date.now() % 2 === 1) {
console.log('当前时间为奇数,可以执行')
} else {//如果时间为偶数抛出异常,由调用者来处理
throw new Error('当前时间为偶数,无法执行')
}
}
// 捕获异常处理
try {
something()
} catch (error) {
alert(error.message)//弹框弹出异常信息
}
Promise是什么?
- Promise 是JS中进行异步编程的显得解决方案
- 从语法上说 Promise 是一个构造函数
- 从功能上说 Promise 对象用来封装一个异步操作并可以获取其结果
Promise优点
- 指定回调函数的方式更加灵活,以前必须在启动异步任务前指定回调函数,promise:启动异步任务 => 返回promise对象 => 给promise对象绑定回调函数(甚至可以在异步任务之后指定)
- 支持链式调用,解决了回调地狱的问题。
- 什么是回调地狱?回调函数会嵌套调用,外部回调函数异步执行的结果是嵌套的回调函数执行的条件
- 回调地狱不利于阅读/不便处理异常
- 可以用promise链式调用解决回调地狱
- 最好用ansyc/await解决回调地狱
- 什么时候会使用函数嵌套?多个串联的异步操作。
- 规范了回调函数
Promise的状态改变
三种状态:pending
就绪状态 resolved
成功状态 rejected
失败状态
pending => resolved
或 pending => rejected
已决状态下,只有成功和失败两种变化,promise 对象只能改变一次,无论成功还是失败都有一个结果数据,成功结果称 value
,失败结果称 reason
Promise的基本使用
//创建一个新的promise对象
const p = new Promise((resolve, reject) => {
//执行异步操作任务
setTimeout(() => {
const time = Date.now() //设置返回时间为偶数成功,为奇数失败
if (time % 2 === 0) { // 如果成功了,调用 resolve(value)
resolve('成功的数据=' + time)
} else { // 如果失败了,调用 reject(reason)
reject('失败的数据,time=' + time)
}
}, 1000);
})
p.then(
value => { //接收得到成功的value数据 onResolved
console.log('成功的回调', value)
},
reason => { //接收得到的失败的reason数据 onRejected
console.log('失败的回调', reason)
}
)
Promise API
Promise 构造函数
Promise(excutot) {}
excutor
函数:同步执行 (resolve, reject) => {}
resolve
函数:内部定义成功时我们调用的函数 value => {}
reject
函数:内部定义失败时我们调用的函数 reason => {}
excutor
会在Promise
内部立即同步回调,异步操作在执行器中执行
then 方法
Promise.prototype.then(onResolved, onRejected) => {}
onResolved
函数:成功的回调函数 (value) => {}
onRejected
函数:失败的回调函数(reason) => {}
指定用于得到成功value的成功回调和用于得到失败reason的失败回调,返回一个新的promise对象,所以可以链式调用
catch 方法
Promise.proototype.catch(onRejected) => {}
onRejected
函数:失败的回调函数 (reason) => {}
then()
的语法糖,相当于then(undefined, onRejected)
resolve 方法
Promise.resolve(value) => {}
value
:成功的数据或promise对象
返回一个成功/失败的promise对象
reject 方法
Promise.reject(reason) => {}
reason
:失败的原因
返回一个失败的promise对象
all 方法
Promise.all(iterable)
这个方法返回一个新的promise
对象,该promise
对象在iterable
参数对象里所有的promise
对象都成功的时候才会触发成功,一旦有任何一个iterable
里面的promise
对象失败则立即触发该promise
对象的失败。这个新的promise
对象在触发成功状态以后,会把一个包含iterable
里所有promise
返回值的数组作为成功回调的返回值,顺序跟iterable
的顺序保持一致;如果这个新的promise
对象触发了失败状态,它会把iterable
里第一个触发失败的promise
对象的错误信息作为它的失败错误信息。Promise.all
方法常被用于处理多个promise
对象的状态集合。(可以参考jQuery.when
方法)
const p1 = new Promise((resolve, reject) => {
resolve(1)
})
const p2 = Promise.resolve(2)
const p3 = Promise.reject(3)
const pAll = Promise.all([p1, p2, p3])
pAll.then(
values => {
console.log('all onResolved()', values)
},
reason => {
console.log('all onRejected()', reason)
}
)
race 方法
Promise.race(iterable)
当iterable
参数里的任意一个子promise
被成功或失败后,父promise
马上也会用子promise
的成功返回值或失败详情作为参数调用父promise
绑定的相应句柄,并返回该promise
对象。谁先完成返回谁
const pRace = Promise.race([p3,p1,p2])
pRace.then(
value => {
console.log('race onResolved()', value)
},
reason => {
console.log('race onRejected()', reason)
}
)