三种状态
pending
rejected
resolved
只能 pending 到 resolved
或者 pending 到 rejected
在new Promise的时候可以传入一个函数,第一个参数代表 resolve,第二个参数代表 reject,当然两个参数名可以自己定义。
看下面这个例子
//首先定义了一个 数组
let subscribers = []
//给数组添加元素的方法
function addSubscriber(callback) {
subscribers.push(callback)
}
// 普通函数
function arr() {
return 'arr返回'
}
//定义一个Promise
let promiseTest = new Promise(resove => {
//自动执行 打印111 最先打印的
console.log(111)
//将函数引用的形式push到数组里面
addSubscriber(() => {
resove(arr()) })
})
// let promiseTest = new Promise(resove => {
// addSubscriber(resove(arr()))
// }) //
console.log(subscribers) //[f] 第一项是函数的引用
console.log(promiseTest) //Promise处于 pending 状态
//调用数组的第一项
subscribers[0]()
console.log(subscribers)
//调用了 resolve()
// 返回状态 resolved
console.log(promiseTest)
我们在new Promise的时候并没有将 resolve()成功的结果返还出去,也没有将失败的结果返还出去,这个时候这个Promise对象一直处于Pending状态,直到我们调用了这个数组的第零项,状态从Pending编程了fulfilled(也就是resolved),表示成功了,在没调用函数之前,这个Promise一直处于挂起的状态,并没用返回,数组就是Promise状态收集器。
在看这个例子 我们只是稍微改动一下push到数组里面的东西
let subscribers = []
//给数组添加元素的方法
function addSubscriber(callback) {
subscribers.push(callback)
}
// 普通函数
function arr() {
return 'arr返回'
}
//定义一个Promise
// let promiseTest = new Promise(resove => {
// //自动执行 打印111
// console.log(111)
// //将函数引用的形式push到数组里面
// addSubscriber(() => { resove(arr()) })
// })
let promiseTest = new Promise(resove => {
addSubscriber(resove(arr()))
}) //
console.log(subscribers)
console.log(promiseTest) //Promise处于 resolved状态
第一次打印promiseTest的时候他的状态已经变成了resolved了,不能存储状态。
token静默刷新:
用户登录一段事件后,访问接口需要携带的token过期,但是用户一直在操作,直接跳转到登录页面很不友好,可以在用户不知道的情况下直接刷新token,如可以我们在axios相应拦截中判断。
在token静默刷新的时候,我们就可以这样存储Promise,等token刷新过后,在进行resolve(),返回数据。
这个参考了一位大佬的 前端Promise总结笔记
然后自己巧了一遍,理解了很多,收获了很多。
手写 Promise 代码
我在里面做了很多注释,大家可以看看,学习一下,我也是为了给自己加深印象~
//首先 在Promise构造函数中 写两个方法
//Promise参数是两个函数 定义状态
//then函数 返回Promise 判断状态 回调
let data = 'xxx'
let p = new Promise((resolve, reject) => {
if (true) {
resolve(data) } else {
reject(data) } })
p.then((res) => {
}, (err) => {
})
//自定义函数Promise
function Promise(executor) {
//设置Promise 状态
this.PromiseState = 'pending';
//返回值 默认为null
this.PromiseResult = null;
//保存实例对象的this值
const that = this;
//定义callback属性,保存pending状态的回调函数
// this.callback = {}
this.callbacks = []
//自定义resolve函数
function resolve(data) {
//控制改变状态次数 promise只能改变一次状态
if (that.PromiseState !== 'pending') return
that.PromiseState = 'resolved';
that.PromiseResult = data;
//异步任务成功后执行回调函数
// if (that.callback.onResolved) {
// that.callback.onResolved(data)
// }
//异步任务成功后执行回调函数
setTimeout(() => {
that.callbacks.forEach(item => {
item.onResolved(data)
})
}, 0)
}
// 自定义reject函数
function reject(data) {
//控制改变状态次数 promise只能改变一次状态
if (that.PromiseState !== 'pending') return
that.PromiseState = 'rejected';
that.PromiseResult = data;
//异步任务失败后执行回调函数
// if (that.callback.onRejected) {
// that.callback.onRejected(data)
// }
//异步任务失败后执行回调函数
setTimeout(() => {
that.callbacks.forEach(item => {
item.onRejected(data)
})
}, 0)
}
try {
//同步调用 执行器函数
executor(resolve, reject)
} catch (err) {
// throw err
//更改Promise对象为失败状态
reject(err)
}
}
//封装then函数到原型链
Promise.prototype.then = function (onResolved, onRejected) {
let that = this
//判断回调函数是否存在
if (typeof onResolved !== 'function') {
onResolved = value => value
}
if (typeof onRejected !== 'function') {
onResolved = err => {
throw err
}
}
return new Promise((resolve, reject) => {
//重复代码封装
function callback(type) {
try {
//获取回调函数执行的结果
let result = type(that.PromiseResult)
//判断
if (result instanceof Promise) {
//如果是Promise对象
result.then(res => {
resolve(res) }, err => {
reject(err) })
} else {
//结果对象状态是 成功
resolve(result)
}
} catch (err) {
reject(err)
}
}
//Promise状态是resolved 走的 resolve函数
if (this.PromiseState === 'resolved') {
// onResolved(this.PromiseResult)
callback(onResolved)
}
//Promise状态是rejected 走的 reject函数
if (this.PromiseState === 'rejected') {
// onRejected(this.PromiseResult)
callback(onRejected)
}
//Promise状态为'pending'时,保存状态
if (this.PromiseState === 'pending') {
// this.callback = {
// onResolved,
// onRejected
// }
this.callbacks.push({
onResolved: function () {
callback(onResolved)
// try {
// //获取回调函数执行的结果
// let result = onResolved(this.PromiseResult)
// //判断
// if (result instanceof Promise) {
// //如果是Promise对象
// result.then(res => { resolve(res) }, err => { reject(err) })
// } else {
// //结果对象状态是 成功
// resolve(result)
// }
// } catch (err) {
// reject(err)
// }
},
onRejected: function () {
callback(onRejected)
// try {
// //获取回调函数执行的结果
// let result = onResolved(this.PromiseResult)
// //判断
// if (result instanceof Promise) {
// //如果是Promise对象
// result.then(res => { resolve(res) }, err => { reject(err) })
// } else {
// //结果对象状态是 成功
// resolve(result)
// }
// } catch (err) {
// reject(err)
// }
}
})
}
})
}
//添加catch 方法
Promise.prototype.catch = function (onRejected) {
return this.then('', onRejected)
}
//添加 Promise.resolve() 方法
Promise.resolve = function (value) {
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(res => {
resolve(res) }, err => {
reject(err) })
} else {
reject(value)
}
})
}
//添加 Promise.reject() 方法
Promise.reject = function (value) {
return new Promise((resolve, reject) => {
reject(value)
})
}
//all方法
//全部成功才返回成功res数组
Promise.all = function (arr) {
//添加变量
let num = 0
//存放成功结果的数组
let arrList = []
return new Promise((resolve, reject) => {
for (let i = 0; i < arr.length; i++) {
arr[i].then(res => {
num++
arrList[i] = res
if (num == arrList.length) {
//只有全都成功的话 才返回正确的结果
resolve(arrList)
}
}, err => {
//失败
reject(err)
})
}
})
}
//race方法
//请求多个,返回第一个成功等待额
Promise.race = function (arr) {
//根据promise状态值会改变一次 的特性
return new Promise((resolve, reject) => {
for (let i = 0; i < arr.length; i++) {
arr[i].then(res => {
//成功
resolve(res)
}, err => {
//失败
reject(err)
})
}
})
}