目录
2.4 Promise.resolve()与Promise.reject()
2.8 改变promise状态和指定回调函数(.then)执行顺序
第一章 介绍promise
1.1 简介
Promise 是ES6 新增的一个异步调用解决方案,它的出现是为了解决异步函数的 回调地狱 的问题
1.2 什么是地域回调
- "回调地域":指的是编程当中"多级的异步的嵌套调用"的问题
- 简单的说就是一个函数里面又套用了一个函数,跟“套娃”一样,当然,如果回调函数少的话,问题还是不是特别大,嵌套的函数很多时,如果这嵌套内的一个函数出现了问题,那么我们一下定位不到问题所在。
第二章 promise理论
let p = new Promise((resolve,reject)=>{
resolve('ok')
})
console.log('了解promise', p)
- 我们先了解这3个API,Prototype -> Promise 表示promise类型;PromiseState以及PromiseResult很重要,如下:
2.1 promise的状态
PromiseState
- 三种状态:pending(等待态)、resolved/fullfilled(成功态)、rejected(失败态)
- 只有两种可能的变换 —— 从等待态转变为成功态或者等待态转变为失败态
- pending -> resolved/fulllfilled
- pending -> rejected
- 一个promise对象只能改变一次,状态由等待态发生改变之后就不会再发生改变了
- 无论成功还是失败都会有一个结果数据
- 注意该文章:成功的结果一般为value,失败的结果一般为reason
2.2 promise对象的值
PromiseResult
- 保存对象(成功/失败)的结果:resolve的结果/reject的结果
2.3 promise构造函数
// promise构造函数
const p = new Promise((resolve, reject) => {
// 对于(resolve, reject) => {}中的代码是同步执行的代码
// 执行器函数里面确定返回的状态与值
// 修改对象的状态为rejected失败状态
reject('error')
})
// 执行catch方法
p.catch(reason=>{
console.log('报错',reason)
})
// promise构造函数
const p1 = new Promise((resolve, reject) => {
// 对于(resolve, reject) => {}中的代码是同步执行的代码
// 执行器函数里面确定返回的状态与值
// 修改对象的状态为fulfilled成功状态
resolve('success')
})
// 执行catch方法
p1.then(value=>{
console.log('成功',value)
})
Promise(excutor)
- excutor函数:执行器函数(resolve,reject) =>{}
- resolve函数:内部定义成功时我们调用的函数value=>{}
- eject函数:内部定义失败时我们调用的函数reason=>{}
- 说明:对于excutor执行器函数会在Promise内部立即同步调用,异步在执行器中执行
2.4 Promise.resolve()与Promise.reject()
const p1 = Promise.reject('reject:p1')
const p2 = Promise.resolve('resolve:p2')
const p3 = Promise.resolve('resolve:p3')
const p4 = Promise.resolve(new Promise((resolve, reject) => {
resolve('resolve-Promise:p4')
}))
console.log(p1,p2,p3,p4)
- Promise.resolve():返回一个成功的数据/失败的promise对象
- Promise.reject():返回一个失败的promise对象
- 返回一个状态为:rejected失败,结果为:reject:p1的promise对象
- 返回一个状态为:fulfilled成功,结果为resolve:p2的promise对象
- 返回一个状态为:fulfilled成功,结果为resolve:p3的promise对象
- 返回了一个promise对象,状态为fulfilled成功,结果为该promise对象里返回的结果:resolve-Promise:p4
2.5 promise常用的几种方法
let p1 = new Promise((resolve,reject)=>{
resolve('ok')
})
// let p2 = Promise.resolve('success')
let p2 = Promise.reject('no')
let p3 = Promise.resolve('yes')
// let p3 = Promise.reject('No')
const resultAll = Promise.all([p1,p2,p3])
const resultRace = Promise.race([p1,p2,p3])
console.log('all', resultAll)
console.log('race', resultRace)
- promises: 包含n个promise的数组
2.5.1 Promise.all(promises)
- 返回一个新的promise,只有所有的promise都成功才成功(PromiseResult为每个成功状态的数组), 只要有一个失败就直接失败(PromiseResult为最先失败的那个值)
let p1 = new Promise((resolve,reject)=>{
resolve('ok')
})
let p2 = Promise.resolve('success')
// let p2 = Promise.reject('no')
let p3 = Promise.resolve('yes')
// let p3 = Promise.reject('No')
const resultAll = Promise.all([p1,p2,p3])
console.log('all', resultAll)
2.5.2 Promise.race(promises)
- 返回一个新的promise,第一个完成的promis的结果状态就是最终的结果状态,不管是失败还是成功
let p1 = new Promise((resolve,reject)=>{
reject('ok')
})
let p2 = Promise.resolve('success')
// let p2 = Promise.reject('no')
let p3 = Promise.resolve('yes')
// let p3 = Promise.reject('No')
const resultRace = Promise.race([p1,p2,p3])
console.log('race', resultRace)
2.5.3 Promise.finally
- finally方法的回调函数不接受任何参数,也不知道前面的 Promise 状态到底是fulfilled还是rejected,但是最终都会执行finally的方法
2.6 promise状态修改
let p = new Promise((resolve, reject) => {
// 1、resolve函数 pending==>fullfilled 等待态转变为成功态
// resolve('ok')
// 2、resolve函数 pending==>reject 等待态转变为失败态
// reject('error')
// 3、抛出错误
throw '111'
})
console.log(p)
- 1、resolve函数 pending==>fullfilled 等待态转变为成功态
- 2、resolve函数 pending==>reject 等待态转变为失败态
- 3、抛出错误
2.7 promise执行多个回调
let p = new Promise((resolve, reject) => {
resolve('ok')
})
p.then(value=>{
console.log(value)
})
p.then(value=>{
alert(value)
})
console.log(p)
- 一个promise指定多个成功/失败回调函数,当promise改变为对应的状态时,都会调用
2.8 改变promise状态和指定回调函数(.then)执行顺序
let p = new Promise((resolve, reject) => {
// setTimeout(()=>{
resolve('ok')
// },2000)
})
p.then(value=>{
console.log('value', value)
},reason=>{
console.log('reason', reason)
})
console.log('p', p)
- 都有可能,正常情况也可以先改变状态再执行回调,但先执行指定回调再改变状态
- 如何先改变状态再指定回调?——先在执行器中直接调用resolve()/reject(),再调用.then;
- 如何先先执行指定回调再改变状态?——在执行器中给resolve()/reject()设置定时器,延迟执行
2.9 then方法返回的结果由什么决定
let p = new Promise((resolve, reject) => {
resolve('ok');
});
//执行 then 方法
let result = p.then(value => {
//1. 抛出错误
throw '出了问题';
//2. 返回结果是非 Promise 类型的对象
// console.log("value", value);
// return 521;
//3. 返回结果是 Promise 对象
// return new Promise((resolve, reject) => {
// resolve('success');
// // reject('error');
// });
}, reason => {
console.warn(reason);
});
console.log("result", result);
- 1、throw抛出错误
- 2、返回结果是非 Promise 类型的对象
-- then方法内部return值,最终promiseState结果为fulfilled,promiseResult结果为return的值
-- then方法内部直接执行console.log("value", value),不return ,最终promiseState结果为fulfilled,promiseResult结果为return的值,没有return默认undefined
- 3、返回结果是 Promise 类型的对象
-- 看promise对象返回的时什么值和状态
2.10 promise串联多个任务
let p = new Promise((resolve, reject) => {
setTimeout(()=>{
resolve('ok')
},2000)
})
p.then(value=>{
console.log(value)
return new Promise((resolve, reject) => {
resolve('success')
})
}).then(value=>{
console.log(value) //success
}).then(value=>{
console.log(value) //undefined
})
- promise的then()返回一个新的promise,可以看成then()的链式调用;通过then的链式调用串联多个同步/异步任务
2.11 异常穿透现象catch
let p = new Promise((resolve, reject) => {
setTimeout(()=>{
resolve('ok')
},2000)
})
p.then(value=>{
console.log(value)
return new Promise((resolve, reject) => {
resolve('success')
})
}).then(value=>{
console.log(value) //success
throw '111'
}).then(value=>{
console.log(value)
}).catch(reason=>{
console.warn(reason)
})
- 异常穿透:当使用promisee的链式调用时,可以在最后指定失败的回调;前面任何操作出了异常,都会传到最后失败的回调中处理,之后不再执行后面的回调函数
2.12 中段promise链
let p = new Promise((resolve, reject) => {
setTimeout(()=>{
resolve('ok')
},2000)
})
p.then(value=>{
console.log(value)
return new Promise((resolve, reject) => {
resolve('success')
})
}).then(value=>{
console.log(value) //success
console.log(111)
// throw '111'
return new Promise(()=>{})
}).then(value=>{
console.log(value) //undefined
console.log(222)
}).then(value=>{
console.log(value) //undefined
console.log(333)
}).catch(reason=>{
console.warn(reason)
})
-
中断promise链的唯一方法:在回调函数中返回一个pendding状态的promise对象--return new Promise(()=>{})