Promise是什么
- 抽象表达
- Promise是Es6规范
- Promise是JS中进行异步编程的新解决方案(旧方案是单纯使用回调函数)
- 具体表达
- 从语法上来说:Promise是一个构造函数
- 从功能上来说:Promise对象用来封装一个异步操作并可以获取其成功/失败的结果值
为什么要使用Promise
- promise支持链式调用,能解决回调地狱。回调地狱:不便于阅读;不便于异常处理
- 指定回调函数的方式更加灵活
- 旧的:必须在启动异步任务之前指定
- promise:启动异步任务 => 返回promise对象 => 给promise对象绑定回调函数(甚至可以再异步任务结束后指定多个)
promise的状态改变
实例对象中的一个属性 [PromiseState]
- pending 未决定的
- resolved/fullfilled成功
- rejected 失败
- pending变为resolved
- pending变为rejected
说明:只有这两种,且
一个promise对象只能改变一次;无论变为成功还是失败,都会有一个结果数据;成功的结果数据一般称为value,失败的结果数据一般称为reason
Promise对象的值
实例对象中的另一个属性 [PromiseResult] 保存着对象成功/失败的结果
- resolve
- reject
如何使用Promise
-
Promise构造函数:Promise(executor){}
- executor函数:执行器(resolve, reject) => {}
- resolve函数:内部定义成功时我们调用的函数 value => {}
- reject函数:内部定义失败时我们调用的函数 reason => {}
executor会在Promise内部立即同步调用,异步操作在执行器中执行
let p = new Promise( (resolve, reject) => { console.log('111'); }) console.log('222'); // 111 222 -
Promise.prototype.then:(onResolved, onRejected) => {}
- onResolved函数:成功的回调函数 (value) => {}
- onRejected函数:失败的回调函数 (reason) => {}
指定用于得到成功value的成功回调和用于得到失败reason的失败回调返回一个新的promise对象
-
Promise.prototype.catch
-
Promise.resolve(value) => {}
- value:成功的数据或promise对象 说明:返回一个成功/失败的promise对象
let p1 = Promise.resolve(20); // 如果传入的参数为非Promise类型的对象,则返回的结果为成功的promise对象 // 如p2的Promise对象,则参数的结果决定了resolve的结果 let p2 = Promise.resolve(new Promise((resolve, reject) => { resolve('ok'); })) console.log(p2); // [PromiseState]:fulfilled [PromiseResult]: "ok" -
Promise.reject:(reason) => {}
- reason:失败的原因 说明:返回一个失败的promise对象
// 传任何东西都是失败 就算传入一个新的promise也是 let p1 = Promise.reject(20); let p2 = Promise.reject('ee'); console.log(p1); // [[PromiseState]]: "rejected" [[PromiseResult]]: 20 console.log(p2); // [[PromiseState]]: "rejected" [[PromiseResult]]: "ee" let p3 = Promise.reject(new Promise((resolve, reject) => { resolve('ok') })) console.log(p3); -
Promise.all:(primises) => {}
- promises:包含n个promise的数组 说明:返回一个新的promise,只有所有的promise都成功才成功,只要有一个失败了就直接失败
// 全部成功时 let p1 = new Promise((resolve, reject) => { resolve('ok'); }) let p2 = Promise.resolve('success'); let p3 = Promise.resolve('yes'); const res = Promise.all([p1,p2,p3]); console.log(res); // [[PromiseState]]: "fulfilled" [[PromiseResult]]: Array(3) // 含失败直接失败 let p1 = new Promise((resolve, reject) => { resolve('ok'); }) let p2 = Promise.resolve('success'); let p3 = Promise.reject('no'); const res = Promise.all([p1,p2,p3]); console.log(res); // [[PromiseState]]: "rejected" [[PromiseResult]]: "no" -
Promise.race: (promises) => {}
-
promises:包含n个promise的数组 说明:返回一个新的primise,第一个完成的promise的结果状态就是最终的结果状态
-
promise的几个关键问题
- 如何改变promise的状态
- resolve(value):如果当前是pending就会变为resolved
- reject(reason):如果当前是pending就会变为rejected
- 抛出异常:如果当前是pending就会变为rejected
let p1 = new Promise((resolve, reject) => {
// 1. resolve函数
// resolve('ok'); // [[PromiseState]]: "fulfilled" [[PromiseResult]]: "ok" pending变fulfilled
// 2. reject函数
// reject('error') // [[PromiseState]]: "rejected" [[PromiseResult]]: "error" pending变rejected
// 3. 抛出错误
throw '出问题了' // [[PromiseState]]: "rejected" [[PromiseResult]]: "出问题了" pending变rejected
})
console.log(p1);
- 一个promise指定多个成功/失败回调函数,都会调用吗?
- 当promise改变为对应状态时都会调用
// resolve时
let p1 = new Promise((resolve, reject) => {
resolve('ok');
})
p1.then(value => {
console.log(value); // 执行
})
p1.then(value => {
alert(value);// 执行
})
console.log(p1);
// reject时
let p1 = new Promise((resolve, reject) => {
reject('error');
})
p1.catch(value => {
console.log(value); // 执行
})
p1.catch(value => {
alert(value);// 执行
})
console.log(p1);
- 改变promise状态和指定回调函数谁先谁后?
-
都有可能,正常情况下是先指定回调再改变状态,但也可以先改状态再指定回调
-
如何先改状态再指定回调?
- 在执行器中直接调用resolve()/reject()
- 延迟更长时间才调用then()
-
什么时候才能得到数据?