首页 > 编程语言 >Promise源码和静态方法

Promise源码和静态方法

时间:2023-03-25 09:11:52浏览次数:50  
标签:status resolve 静态方法 log 源码 Promise reject console

Promise源码

index.html文件进行测试,Promise.js文件写源码

 

 

 

 Promise是一个类,我们使用class进行Promise的声明

js

class Promise {}

html

<script src="./Promise.js"></script>
<script>
    let p = new Promise((resolve, reject) => {
        resolve(1)
    })
    console.log(p)
</script>

这里还没有状态会返回一个空的Promise,里边的代码是立即同步执行的

声明resolve和reject

js,executor是立即执行函数,执行的函数时new Promise传入的函数

class Promise {
    constructor(executor) { // executor是一个立即执行函数,A+规范规定的名字,别的也可以
        executor(1,2) // 立刻执行,执行的是我们new Promise时传入的函数
    }
}

html,传入resolve和reject之后,返回值是1和2

<script src="./Promise.js"></script>
<script>
    let p = new Promise((resolve, reject) => {
        console.log(resolve, reject) // 1 2
    })
    console.log(p)
</script>

成功resolve和失败两种状态已经声明完成了,但是我们传入这两种状态就会获得返回值,不会判断成功或者失败。

 js

class Promise {
    constructor(executor) { // executor是一个立即执行函数,A+规范规定的名字,别的也可以
        let resolve = (value) => {
            console.log('成功的信息', value)
        }
        let reject = (reason) => {
            console.log('失败的信息', reason)
        }
        executor(resolve,reject) // 立刻执行,执行的是我们new Promise时传入的函数
    }
}

html

<script src="./Promise.js"></script>
<script>
let p = new Promise((resolve, reject) => {
console.log(resolve, reject)
resolve(1) // 成功的信息 1
reject(2) // 失败的信息 2
})
console.log(p)
</script>

处理Promise的三种状态

状态是实例独有的属性,也是不可逆转的,所以我们要进行,状态的更新,进行对应状态的赋值(更新成功或者失败之后的值)。这时这里状态只能被修改一次(pending修改状态只能修改一次叫做状态凝固),只有pending状态才可以被修改,如果不是pending状态不能被修改。

js,这里做了,添加状态更新,然后进行赋值,添加判断,是pending状态才可以进行修改

class Promise {
    constructor(executor) {
        this.status = 'pending'; // 默认状态
        this.value = undefined; // 成功的值
        this.reason = undefined; // 失败的原因
        let resolve = (value) => {
            if (this.status === 'pending') {
                this.status = 'resolved'; // 更新状态
                this.value = value; // 更新成功的值
            }
        }
        let reject = (reason) => {
            if (this.status === 'pending') {
                this.status = 'rejected'; // 更新状态
                this.reason = reason; // 更新失败的原因
            }
        }
        executor(resolve,reject) // 立刻执行,执行的是我们new Promise时传入的函数
    }
}

html

<script src="./Promise.js"></script>
<script>
    let p = new Promise((resolve, reject) => {
        resolve(1) // 成功的信息 1
        reject(2) // 失败的信息 2
    })
    console.log(p)
</script>

可以实现初步的then和catch操作

首先我们添加给原型上,不添加到实例上。添加到实例上,会浪费性能,用不用他都有,添加到原型上不会浪费性能,用的时候才有。添加then方法,传入两个参数成功状态和失败状态,进行判断,判断成功之后,执行成功的方法,传入成功的值。判断失败之后,执行失败的方法,传入失败的原因。执行传入的函数出错的时候(是真的出错了),使用try catch捕获executor函数的执行错误,return一个错误的回调reject,进行返回。

js,添加了then方法,进行状态的判断,然后进行回调。try catch捕获,传入的函数报错了,返回一个错误的回调

class Promise {
    constructor(executor) {
        this.status = 'pending'; // 默认状态
        this.value = undefined; // 成功的值,给then方法中的回调函数使用
        this.reason = undefined; // 失败的原因,给catch方法中的回调函数使用
        let resolve = (value) => {
            if (this.status === 'pending') {
                this.status = 'resolved'; // 更新状态
                this.value = value; // 更新成功的值
            }
        }
        let reject = (reason) => {
            if (this.status === 'pending') {
                this.status = 'rejected'; // 更新状态
                this.reason = reason; // 更新失败的原因
            }
        }
       try {
           executor(resolve,reject) // 立刻执行,执行的是我们new Promise时传入的函数
       } catch (e) {
              reject(e) // 如果执行失败,就直接执行失败的逻辑
       }
        // this.then() // 为什么不使用this添加,添加给实例上,会很浪费性能
    }
    then(onFulfilled, onRejected) { // 这里添加给原型上
        // onFulfilled => p成功后,调用的回调函数
        // onRejected => p失败后,调用的回调函数
        if (this.status === 'resolved') { // 判断状态成功之后
            onFulfilled(this.value); // 进行成功的函数调用,传入成功的值
        }
        if (this.status === 'rejected') { // 判断状态失败之后
            onRejected(this.reason); // 进行失败的函数调用,传入失败的原因
        }
    }
}

html,可以使用.then和。catch进行初步的链式调用了

<script src="./Promise.js"></script>
<script>
    let p = new Promise((resolve, reject) => {
        resolve(1) // 成功的信息 1
        reject(2) // 失败的信息 2
    })
    // console.log(p)
    p.then(res => {
        console.log('1-' + res)
    }, err => {
        console.log('2-' + err)
    })
</script>

实现异步操作

当我们一秒之后,才将Promise的状态执行成成功或者失败,如果不做处理,是不会执行后边的函数的,then不会进行一个状态的判断。这里的回调,希望再Promise的状态更新程fulfiled。如果有异步的操作,不是立即满足条件的,就等条件满足之后,再来调用这个函数。then会被先执行,然后执行回调函数。

js创建一个空数组,然后进行pending状态的判断,数组添加成功的状态和成功的值,添加失败的状态和失败的值。最后在成功或者失败的状态中,进行数组循环,和方法的发布

class Promise {
constructor(executor) {
this.status = 'pending'; // 默认状态
this.value = undefined; // 成功的值,给then方法中的回调函数使用
this.reason = undefined; // 失败的原因,给catch方法中的回调函数使用
this.onFulfilledCallbacks = []; // 存放成功的回调函数
this.onRejectedCallbacks = []; // 存放失败的回调函数
let resolve = (value) => {
if (this.status === 'pending') {
this.status = 'resolved'; // 更新状态
this.value = value; // 更新成功的值
this.onFulfilledCallbacks.forEach(fn => fn()); // 发布
}
}
let reject = (reason) => {
if (this.status === 'pending') {
this.status = 'rejected'; // 更新状态
this.reason = reason; // 更新失败的原因
this.onRejectedCallbacks.forEach(fn => fn()); // 发布
}
}
// console.log('1s之后resolve函数执行了')
try {
executor(resolve,reject) // 立刻执行,执行的是我们new Promise时传入的函数
} catch (e) {
reject(e) // 如果执行失败,就直接执行失败的逻辑
}
// this.then() // 为什么不使用this添加,添加给实例上,会很浪费性能
}
then(onFulfilled, onRejected) { // 这里添加给原型上
// onFulfilled => p成功后,调用的回调函数
// onRejected => p失败后,调用的回调函数
if (this.status === 'resolved') { // 判断状态成功之后
onFulfilled(this.value); // 进行成功的函数调用,传入成功的值
}
if (this.status === 'rejected') { // 判断状态失败之后
onRejected(this.reason); // 进行失败的函数调用,传入失败的原因
}
// console.log('then函数执行了')
if (this.status === 'pending') { // 判断状态是等待的时候
this.onFulfilledCallbacks.push(() => { // 将成功的回调函数存放到数组中
onFulfilled(this.value); // 进行成功的函数调用,传入成功的值
});
this.onRejectedCallbacks.push(() => { // 将失败的回调函数存放到数组中
onRejected(this.reason); // 进行失败的函数调用,传入失败的原因
});
}
}}

html

<script src="./Promise.js"></script>
<script>
    let p = new Promise((resolve, reject) => {
        setTimeout(() => {
            reject('失败')
        }, 1000)
    })
    // console.log(p)
    p.then(res => {
        console.log('1-' + res)
    }, err => {
        console.log('2-' + err)
    })
</script>

实现链式调用

上一个.then要返回一个Promise对象,不然返回undefined是没有.then方法的

js中new了一个新的promise方法,然后进行return,新的promise中,获取上次运行的返回值,进行一个返回值的传入,传入到下一个使用

class Promise {
    constructor(executor) {
        this.status = 'pending'; // 默认状态
        this.value = undefined; // 成功的值,给then方法中的回调函数使用
        this.reason = undefined; // 失败的原因,给catch方法中的回调函数使用
        this.onFulfilledCallbacks = []; // 存放成功的回调函数
        this.onRejectedCallbacks = []; // 存放失败的回调函数
        let resolve = (value) => {
            if (this.status === 'pending') {
                this.status = 'resolved'; // 更新状态
                this.value = value; // 更新成功的值
                this.onFulfilledCallbacks.forEach(fn => fn()); // 发布
            }
        }
        let reject = (reason) => {
            if (this.status === 'pending') {
                this.status = 'rejected'; // 更新状态
                this.reason = reason; // 更新失败的原因
                this.onRejectedCallbacks.forEach(fn => fn()); // 发布
            }
        }
        // console.log('1s之后resolve函数执行了')
        try {
           executor(resolve,reject) // 立刻执行,执行的是我们new Promise时传入的函数
       } catch (e) {
              reject(e) // 如果执行失败,就直接执行失败的逻辑
       }
        // this.then() // 为什么不使用this添加,添加给实例上,会很浪费性能
    }
    then(onFulfilled, onRejected) { // 这里添加给原型上
        // onFulfilled => p成功后,调用的回调函数
        // onRejected => p失败后,调用的回调函数
        let promise2 = new Promise((resolve,reject)=>{
            if (this.status === 'resolved') { // 判断状态成功之后
               const x = onFulfilled(this.value); // 进行成功的函数调用,传入成功的值
                // 把我们的返回值返回
                resolve(x);
            }
            if (this.status === 'rejected') { // 判断状态失败之后
                const x = onRejected(this.reason); // 进行失败的函数调用,传入失败的原因
                // 把我们的返回值返回
                reject(x);
            }
            // console.log('then函数执行了')
            if (this.status === 'pending') { // 判断状态是等待的时候
                this.onFulfilledCallbacks.push(() => { // 将成功的回调函数存放到数组中
                    onFulfilled(this.value); // 进行成功的函数调用,传入成功的值
                });
                this.onRejectedCallbacks.push(() => { // 将失败的回调函数存放到数组中
                    onRejected(this.reason); // 进行失败的函数调用,传入失败的原因
                });
            }
        })

        return promise2;
}}

html

<script src="./Promise.js"></script>
<script>
    let p = new Promise((resolve, reject) => {
        // setTimeout(() => {
        //     reject('失败')
        // }, 1000)
        resolve('成功')
    })
    // console.log(p)
    p.then(res => {
        console.log('1-' + res)
        return 100
    }, err => {
        console.log('2-' + err)
    }).then(res => {
        console.log('3-' + res)
        return 200
    }, err => {
        console.log('4-' + err)
    }).then(res => {
        console.log('5-' + res)
    }, err => {
        console.log('6-' + err)
    })
</script>

prmoise链式调用,处理不同的状态

我们在then中return中return一个promise,我们之前获取到的x是前一个.then的返回值,我们需要对x进行分析:1,如果是普通值,直接调用resolve;2,如果是一个Promise对象,看Promise是否成功?如果成功调用resolve如果失败调用reject。推荐:对x进行判断,对x进行处理的代码封装成一个函数

js声明一个函数,进行x的判断


class Promise {
constructor(executor) {
this.status = 'pending'; // 默认状态
this.value = undefined; // 成功的值,给then方法中的回调函数使用
this.reason = undefined; // 失败的原因,给catch方法中的回调函数使用
this.onFulfilledCallbacks = []; // 存放成功的回调函数
this.onRejectedCallbacks = []; // 存放失败的回调函数
let resolve = (value) => {
if (this.status === 'pending') {
this.status = 'resolved'; // 更新状态
this.value = value; // 更新成功的值
this.onFulfilledCallbacks.forEach(fn => fn()); // 发布
}
}
let reject = (reason) => {
if (this.status === 'pending') {
this.status = 'rejected'; // 更新状态
this.reason = reason; // 更新失败的原因
this.onRejectedCallbacks.forEach(fn => fn()); // 发布
}
}
// console.log('1s之后resolve函数执行了')
try {
executor(resolve,reject) // 立刻执行,执行的是我们new Promise时传入的函数
} catch (e) {
reject(e) // 如果执行失败,就直接执行失败的逻辑
}
// this.then() // 为什么不使用this添加,添加给实例上,会很浪费性能
}
then(onFulfilled, onRejected) { // 这里添加给原型上
// onFulfilled => p成功后,调用的回调函数
// onRejected => p失败后,调用的回调函数
let promise2 = new Promise((resolve,reject)=>{
if (this.status === 'resolved') { // 判断状态成功之后
const x = onFulfilled(this.value); // 进行成功的函数调用,传入成功的值
// 把我们的返回值返回
resolvePromise(x,resolve,reject)
}
if (this.status === 'rejected') { // 判断状态失败之后
const x = onRejected(this.reason); // 进行失败的函数调用,传入失败的原因
// 把我们的返回值返回
reject(x);
}
// console.log('then函数执行了')
if (this.status === 'pending') { // 判断状态是等待的时候
this.onFulfilledCallbacks.push(() => { // 将成功的回调函数存放到数组中
onFulfilled(this.value); // 进行成功的函数调用,传入成功的值
});
this.onRejectedCallbacks.push(() => { // 将失败的回调函数存放到数组中
onRejected(this.reason); // 进行失败的函数调用,传入失败的原因
});
}
})
return promise2;
}}
function resolvePromise(x,resolve,reject){
if (x instanceof Promise) { // 判断如果是一个promise,等他成功,等他失败
// x.then(value) => {
// resolve(value)
// },err=> {
// reject(err)
// })
x.then(resolve,reject)
} else {
resolve(x) // 如果不是promise,直接成功即可
}
}
 

html

<script src="./Promise.js"></script>
<script>
    let p = new Promise((resolve, reject) => {
        // setTimeout(() => {
        //     reject('失败')
        // }, 1000)
        resolve('成功')
    })
    // console.log(p)
    p.then(res => {
        console.log('1-' + res)
        return new Promise((resolve, reject) => {
                resolve(100)
        })
    }, err => {
        console.log('2-' + err)
    }).then(res => {
        console.log('3-' + res)
        return 200
    }, err => {
        console.log('4-' + err)
    }).then(res => {
        console.log('5-' + res)
    }, err => {
        console.log('6-' + err)
    })
</script>

处理循环调用的问题

注意点:.then中返回的promise对象,不能是自己,我们自己写这个是正确的,官方的是错的。自己调用自己的返回值

    const p1 = p.then(
        res => {
            console.log('1-' + res)
            return p1
        },
        err => {
            console.log('2-' + err)
        }
    )
    p1.then(data => {
        console.log(data)
    })

判断Promise和x是不是同一个函数,如果是同一个函数就是错的。promise2中的代码开启异步执行,添加微任务,进行try catch捕获

js添加异步任务

 

class Promise {
    constructor(executor) {
        this.status = 'pending'; // 默认状态
        this.value = undefined; // 成功的值,给then方法中的回调函数使用
        this.reason = undefined; // 失败的原因,给catch方法中的回调函数使用
        this.onFulfilledCallbacks = []; // 存放成功的回调函数
        this.onRejectedCallbacks = []; // 存放失败的回调函数
        let resolve = (value) => {
            if (this.status === 'pending') {
                this.status = 'resolved'; // 更新状态
                this.value = value; // 更新成功的值
                this.onFulfilledCallbacks.forEach(fn => fn()); // 发布
            }
        }
        let reject = (reason) => {
            if (this.status === 'pending') {
                this.status = 'rejected'; // 更新状态
                this.reason = reason; // 更新失败的原因
                this.onRejectedCallbacks.forEach(fn => fn()); // 发布
            }
        }
        // console.log('1s之后resolve函数执行了')
        try {
           executor(resolve,reject) // 立刻执行,执行的是我们new Promise时传入的函数
       } catch (e) {
              reject(e) // 如果执行失败,就直接执行失败的逻辑
       }
        // this.then() // 为什么不使用this添加,添加给实例上,会很浪费性能
    }
    then(onFulfilled, onRejected) { // 这里添加给原型上
        // onFulfilled => p成功后,调用的回调函数
        // onRejected => p失败后,调用的回调函数
        let promise2 = new Promise((resolve,reject)=>{
            if (this.status === 'resolved') { // 判断状态成功之后
                try {
                    queueMicrotask(()=>{ // 微任务
                        const x = onFulfilled(this.value); // 进行成功的函数调用,传入成功的值
                        // 把我们的返回值返回
                        resolvePromise(x,resolve,reject,promise2)
                    })
                } catch (e) {
                    reject(e);
                }
            }
            if (this.status === 'rejected') { // 判断状态失败之后
                try {
                    queueMicrotask(()=>{ // 微任务
                        const x = onRejected(this.reason); // 进行失败的函数调用,传入失败的原因
                        // 把我们的返回值返回
                        resolvePromise(x,resolve,reject,promise2)
                    })
                } catch (e) {
                    reject(e);
                }
            }
            // console.log('then函数执行了')
            if (this.status === 'pending') { // 判断状态是等待的时候
                this.onFulfilledCallbacks.push(() => { // 将成功的回调函数存放到数组中
                    onFulfilled(this.value); // 进行成功的函数调用,传入成功的值
                });
                this.onRejectedCallbacks.push(() => { // 将失败的回调函数存放到数组中
                    onRejected(this.reason); // 进行失败的函数调用,传入失败的原因
                });
            }
        })
        return promise2;
}}
function resolvePromise(x,resolve,reject,promise2){
    // 处理循环调用
    if (x === promise2) {
        console.error('循环引用')
        return reject(new TypeError('循环引用'))
    }
    if (x instanceof Promise) { // 判断如果是一个promise,等他成功,等他失败
        // x.then(value) => {
        //     resolve(value)
        // },err=> {
        //     reject(err)
        // })
        x.then(resolve,reject)
    } else {
        resolve(x) // 如果不是promise,直接成功即可
    }
}

html

<script src="./Promise.js"></script>
<script>
    let p = new Promise((resolve, reject) => {
        // setTimeout(() => {
        //     reject('失败')
        // }, 1000)
        resolve('成功')
    })
    console.log(p)
    // p.then(res => {
    //     console.log('1-' + res)
    //     return new Promise((resolve, reject) => {
    //             resolve(100)
    //     })
    // }, err => {
    //     console.log('2-' + err)
    // }).then(res => {
    //     console.log('3-' + res)
    //     return 200
    // }, err => {
    //     console.log('4-' + err)
    // }).then(res => {
    //     console.log('5-' + res)
    // }, err => {
    //     console.log('6-' + err)
    // })

    const p1 = p.then(
        res => {
            console.log('1-' + res)
            return p1
        },
        err => {
            console.log('2-' + err)
        }
    )
</script>

 

标签:status,resolve,静态方法,log,源码,Promise,reject,console
From: https://www.cnblogs.com/hgng/p/17252996.html

相关文章