highlight: a11y-dark
一、基本框架实现
实现以下结构的promise自定义封装
<script>
const p=new Promise((resolve,reject)=>{
resolve('ok')
// reject('err')
// throw('err')
}).then((value)=>{
console.log(value)
},(reason)=>{
console.log(reason)
})
</script>
步骤:
1. 初始结构状态搭建
2. resolve与reject结构搭建
3. throw抛出异常状态改变
4. promise对象状态只修改一次
5. then方法执行回调
<script>
//1.构造函数
function Promise(executor){
//添加属性
//设置初始状态
this.Promisestate ='pedding'
//设置初始值
this.PromiseResult = null
//保存实例对象的this值
const self = this
//2. resolve与reject结构搭建
function resolve(data){
//判断 4. promise对象状态只修改一次
if(self.PromiseState !== 'pedding')return
//(1)修改对象状态(Promisestate)
self.Promisestate='fulfilled'//resolved 解决
//(2)设置对象结果值(PromiseResult)
self.PromiseResult = data
}
function reject(data){
//判断 4. promise对象状态只修改一次
if(self.PromiseState !== 'pedding')return
//(1)修改对象状态(Promisestate)
self.PromiseState="rejected"
//(2)设置对象结果值(PromiseResult)
self.PromiseResult=data
}
//3. throw抛出异常状态改变
try {
//同步调用[执行器函数]
executor(resolve,reject)
}catch(e){
//修改promise对象状态为失败
reject(e)
}
}
//5.添加then方法 (then方法执行回调)
Promise.prototype.then=function(onResolve, onReject){
//调用回调函数 Promisestate
if(this.PromiseState ==='fulfilled'){
onResolve(this.PromiseResult)
}
if(this.PromiseState ==='rejected'){
onReject(this.PromiseResult)
}
}
</script>
二、异步任务回调的执行
setTimeout模拟异步任务回调
<script>
const p=new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('oK');
},1000);
// reject('err')
// throw('err')
}).then((value)=>{
console.log(value)
},(reason)=>{
console.log(reason)
})
</script>
- (异步)回调执行时机:在改变对象状态之后才执行的回调函数
- 同步执行的时机就是在调用then方法的时候调用回调函数
- 在状态改变之前先保存回调函数,注意先声明callback属性
this.callback={}
- 调用成功/失败时的回调函数
三、指定多个回调的实现
指定多个回调,这种写法就会使后面的对象覆盖前面的,只会执行alert;
解决办法,把多个回调函数存在数组里;
修改callback定义,且利用forEach遍历数组对象
四、同步修改状态then方法结果返回
结果:
(因为上述回调函数没有加return,所以PromiseResult为undifined)
同理reject状态执行结果:
关键:如果.then后面的函数返回的是非promise状态的函数,比如undifine,字符串等,状态都是resolve状态的;如果返回的是promise状态的,这个返回的promise状态就决定了.then结果的状态
实现源码:
then方法返回结果:
- 非promise对象的reslove;
- promise对象的resolve和reject;
- 抛出异常情况下,改变状态为失败的reject;
抛出异常情况
五、异步修改状态then方法结果返回
此时状态还是pending,但是这里正确的Promise的then方法返回的应该是
所以我们要修改异步情况下then返回的状态结果;
因为此时状态还是pending,我们要在PromiseState===pedding时进行执行
同时,执行过程同理:
then方法返回结果:
- 非promise对象的reslove;
- promise对象的resolve和reject;
- 抛出异常情况下,改变状态为失败的reject;
代码优化
六、catch方法-异常穿透和值传递
异常穿透:就是在最后指定一个失败的回调,就可以对失败的结果进行处理,包括中间有可能抛出的异常
第一个p.then执行了,紧跟着传的回调函数的参数,传的是onRejected,是一个非函数
值传递
七、Promise.resolve封装
(返回的是promise的对象,返回的状态决定Promise.resolve
去执行什么状态;返回的是成功,Promise.resolve
就是去执行成功,返回的是失败,Promise.resolve
就是去执行失败,返回的是非promise对象。就设置状态为成功)
八、Promise.reject封装
Promise.reject
与Promise.resolve
的不同就是,不管传什么参数,都是执行reject
九、Promise.all封装
如果有一个失败就是返回失败的那一个的状态
十、Promise.race封装
Promise.race
的结果由数组中第一个改变的状态的promise决定
十一、then方法回调的异步执行
源码
//声明构造函数
function Promise(executor) {
//添加属性
//设置初始状态
this.PromiseState = 'pedding'//初始状态
//设置初始值
this.PromiseResult = null
//保存实例对象的this值
const self = this
//声明属性
this.callback = []
//resolve函数
function resolve(data) {
//判断
if (self.PromiseState !== 'pedding') return
//1.修改对象状态(PromiseState)
self.PromiseState = 'fulfilled'//resolved 解决
//2.设置对象结果值(PromiseResult)
self.PromiseResult = data
//调用成功的回调函数
//如果self.callback里面有onResolved
// if (self.callback.onResolved) {
// self.callback.onResolved(data)
// }
setTimeout(() => {
self.callback.forEach(item => {
item.onResolved(data)
})
})
}
//reject函数
function reject(data) {
//判断
if (self.PromiseState !== 'pedding') return
//1.修改对象状态(PromiseState)
self.PromiseState = 'rejected'
//2.设置对象结果值(PromiseResult)
self.PromiseResult = data
//调用失败的回调函数
//如果self.callback里面有onRejected
// if (self.callback.onRejected) {
// self.callback.onRejected(data)
// }
setTimeout(() => {
self.callback.forEach(ittem => {
item.onRejected(data)
})
})
}
try {
//同步调用[执行器函数]
executor(resolve, reject)
} catch (e) {
//修改promise对象状态为失败
reject(e)
}
}
//添加then方法
Promise.prototype.then = function (onResolve, onReject) {
const self = this
//判断回调函数的参数
if (typeof onRejected !== 'function') {
onRejected = reason => {
throw reason
}
}
//值传递 第一个不传 就给它赋默认值
if (typeof onResolved !== 'function') {
onResolved = value => value
}
return new Promise((resolve, reject) => {
//封装函数
function callback(type) {
try {
let result = type(self.PromiseResult)
//判断
if (result instanceof Promise) {
//如果是promise类型对象
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
//如果是非promise类型对象
//结果状态为成功
resolve(result)
}
} catch (e) {
reject(e)
}
}
//调用回调函数 PromiseState
if (this.PromiseState === 'fulfilled') {
setTimeout(() => { callback(onResolve) })
}
if (this.PromiseState === 'rejected') {
setTimeout(() => { callback(onReject) })
}
// (异步)回调执行时机:在改变对象状态之后才执行的回调函数
if (this.PromiseState === 'pedding') {
//保存回调函数
this.callback.push = ({
onResolve: function () {
callback(onResolve)
},
onReject: function () {
callback(onReject)
},
})
}
})
}
//添加catch方法
Promise.prototype.catch = function (onRejected) {
//说明: then()的语法糖, 相当于: then(undefined, onRejected)
return this.then(undefined, onRejected)
}
//添加resolve方法
Promise.resolve = function (value) {
//返回Promise对象
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
//状态设置为成功
resolve(value)
}
})
}
//添加reject方法
Promise.reject = function (reason) {
return new Promise((reason, reject) => {
reject(reason)
})
}
//添加all方法
Promise.all = function (promise) {
//返回结果为promise对象
return new Promise((resolve, reject) => {
let count = 0
let arr = []
//遍历
for (let i = 0; i < promise.length; i++) {
promise[i].then(v => {
//得知对象的状态是成功
//每个promise对象都成功
count++
//将当前promise对象成果的结果存入到数组
arr[i] = v
//判断
if (count === promise.length) {
//修改状态
resolve(arr)
}
}, r => {
reject(r)
})
}
})
}
//添加race方法
Promise.race = function (promise) {
return new Promise((resolve, reject) => {
for (let i = 0; i < promise.length; i++) {
promise[i].then(v => {
//修改返回对象的状态为[成功]
resolve(v)
}, r => {
//修改返回对象的状态为[失败]
reject(r)
})
}
})
}