Promise的基本用法
then()方法
catch()方法
finally()方法
啥也不干,类似中转站
Promise.resolve() 和 Promise.reject()
Promise.resolve()
Promise.reject()
Promise.all()
Promise.race() 和 Promise.allSettled()
Promise.race()
Promise.allSettled()
Promise的注意事项
Promise的应用
Promise基础总结
Promise二次封装axios
为什么二次封装axios? 可以集中对请求和响应做处理。
另外,跨域问题一般在开发环境中出现,生产环境都用的同一域门不存在跨域;
Promise
基础
优点
1.指定回调函数的方式更加灵活; 2.支持链式调用,可以解决回调地狱问题.
案例
Demo1
function rand() {
return Math.ceil(Math.random()*(n-m+1)) + m-1
}
const p = new Promise((resolve, reject) => {
setTimeout(() => {
let n = rand(1, 100)
if (n <= 30) {
resolve(n)
} else {
reject(n)
}
}, 1000)
})
p.then((res) => {
alert('恭喜恭喜,奖品为 10万 RMB 劳斯莱斯优惠券, 您的号码为:' + res)
}, (err) => {
alert('再接再厉, 您的号码为:' + err)
})
Demo2 fs文件操作
const fs = require('fs')
const p = new Promise((resolve, reject) => {
fs.readFile('./resource/content.txt', (err, data) => {
// if(err) throw err
// console.log(data)
if(err) reject(err)
resolve(data)
})
})
p.then(res => {
console.log(res.toString())
}, (err) => {
console.log(err)
})
最后,可在终端运行命令查看结果:node demo.js
Demo3 Promise封装 fs
function mineReadFile(path) {
return new Promise((resolve, reject) => {
require('fs').readFile(path, (err, data) => {
if(err) reject(err)
resolve(data)
})
})
}
mineReadFile('./resource/content.txt').then(res => {
console.log(res.toString())
}, err => {
console.error(err)
})
Demo4 util.promisify方法进行Promise转化
const util = require('util')
const fs = require('fs')
let mineReadFile = util.promisify(fs.readFile) // 返回一个新的函数
mineReadFile('./resource/content.txt').then(res => {
console.log(res.toString())
}, err => {
console.error(err)
})
Promise实例对象结果值属性
const p = new Promise() // 构造函数 得到 实例化对象Promise {} console.log(p) 输出结果: Promise { [PromiseState]: 'rejected' [PromiseResult]: 52 }
Promise的状态
实例对象中的一个属性 [PromiseState] pending 未决定的 resolved / fullfilled 成功 rejected 失败
状态改变: pending -> resolved 或 pending -> rejected
Promise 对象的值
实例对象中的另一个属性 [PromiseResult] 保存着对象[成功/失败]的结果 resolve reject
API
-
Promise构造函数:Promise(executor) {} ①executor函数:执行器 (resolve, reject) => {} ②resolve函数:内部定义成功时调用的函数 res => {} ③reject函数:内部定义失败时调用的函数 err => {} **executor会在Promise内部立即同步调用,异步操作在执行器中执行
-
Promise.prototype.then方法:(onResolved, onRejected) => {} ①onResolved函数:成功的回调函数 res => {} ②onRejected函数:失败的回调函数 err => {}
-
Promise.prototype.catch方法:(onRejected) => {} ①onRejected函数:失败的回调函数 err => {}
-
Promise.resolve(value) **value:成功的数据或promise对象。返回一个成功的promise对象。
-
Promise.reject(reason) **reason:失败的原因。返回一个失败的promise对象。
-
Promise.all(promises:[])
let p1 = new Promise((resolve, reject) => {
resolve('OK')
})
let p2 = Promise.resolve('Success')
let p3 = Promise.resolve('Oh Yeah')
const result = Promise.all([p1, p2, p3])
console.log(result)
** 返回一个新的promise, 只有所有的promise都成功才成功,只要有一个失败了就直接失败
- Promise.race(promises:[])
let p1 = new Promise((resolve, reject) => {
resolve('OK')
})
let p2 = Promise.resolve('Success')
let p3 = Promise.resolve('Oh Yeah')
const result = Promise.race([p1, p2, p3])
console.log(result)
** 返回一个新的promise, 第一个完成的promise的结果状态就是最终的结果状态
Promise的关键问题
Promise对象改变状态的方式
let p = new Promise((resolve, reject) => {
// 1. resolve 函数
resolve('OK') // pending => fulfilled (resolved)
// 2. reject 函数
reject('error') // pending => rejected
// 3. 抛出错误
throw '出问题了'
})
console.log(p)
能否执行多个回调
** 当promise改变为对应状态时都会调用
let p = new Promise((resolve, reject) => {
resolve('OK')
})
// 指定回调 1
p.then(res => {
console.log(res)
})
// 指定回调 2
p.then(res => {
alert(res)
})
改变promise状态和指定回调谁先执行
- 都有可能,正常情况是先指定回调再改变状态,但也可以先改状态再指定回调
- 先改状态再指定回调:①在执行器中直接调用resolve()/reject() ②延迟更长时间才调用then()
- 什么时候拿到数据:①如果先指定的回调,那当状态发生改变时,回调函数就会调用,得到数据;②如果先改变的状态,那当指定回调时,回调函数就会调用,得到数据
promise.then()返回的新promise的结果状态由什么决定?
由then()指定的回调函数执行的结果决定
let p = new Promise((resolve, reject) => {
resolve('ok')
})
let result = p.then(value => {
// console.log(value)
1. 抛出错误
throw '出了问题' // result 返回失败的promise对象
2. 返回结果是非Promise类型的对象
return 521 // result 返回成功的promise对象
3. 返回结果是promise对象
return new Promise((resolve, reject) => {
resolve('success') // result 返回成功的promise对象
reject('error') // result 返回失败的promise对象
})
}, reason => {
console.warn(reason)
})
console.log(result)
①如果抛出异常,新promise变为rejected,reason为抛出的异常 ②如果返回的是非promise的任意值,新promise变为resolved,value为返回的值 ③如果返回的是另一个新promise,此promise的结果就会成为新promise的结果
promise如何串连多个操作任务
- promise的then()返回一个新的promise,可以看成then()的链式调用
- 通过then的链式调用串连多个同步/异步任务
promise异常传透
- 当使用promise的then链式调用时,可以在最后指定失败的回调
- 前面任何操作出了异常,都会传到最后失败的回调中处理
手写Promise Promise的封装
......