前言:
针对js的深入理解,作者学习并撰写以下文章,由于理解认知有限难免存在偏差,请大家指正!所有定义来自mdn。
Promise介绍:
对象表示异步操作最终的完成(或失败)以及其结果值.
描述:
一个 Promise 是一个代理,它代表一个在创建 promise 时不一定已知的值。它允许你将处理程序与异步操作的最终成功值或失败原因关联起来。这使得异步方法可以像同步方法一样返回值:异步方法不会立即返回最终值,而是返回一个 promise,以便在将来的某个时间点提供该值。
一个 Promise 必然处于以下几种状态之一:
- 待定(pending):初始状态,既没有被兑现,也没有被拒绝。
 - 已兑现(fulfilled):意味着操作成功完成。
 - 已拒绝(rejected):意味着操作失败。
 
一个待定的 Promise 最终状态可以是已兑现并返回一个值,或者是已拒绝并返回一个原因(错误)。当其中任意一种情况发生时,通过 Promise 的 then 方法串联的处理程序将被调用。如果绑定相应处理程序时 Promise 已经兑现或拒绝,这处理程序将被立即调用,因此在异步操作完成和绑定处理程序之间不存在竞态条件。
如果一个 Promise 已经被兑现或拒绝,即不再处于待定状态,那么则称之为已敲定(settled)。

Promise.resolve:
        Promise.resolve() 静态方法将给定的值转换为一个 Promise。如果该值本身就是一个 Promise,那么该 Promise 将被返回;如果该值是一个 thenable 对象,Promise.resolve() 将调用其 then() 方法及其两个回调函数;否则,返回的 Promise 将会以该值兑现。
构造MyPromise函数:
   // 构造函数
        // 定义类
        class MyPromise {
            // 添加构造函数
            constructor(func){
                // 定义resolve和reject方法
                const resolve = (value) => {
                    console.log('resolve执行:',value)
                    // // 判断状态是否为pending
                    // if(this.status === 'pending'){
                    //     // 修改状态为fulfilled
                    //     this.status = 'fulfilled'
                    //     // 保存成功的值
                    //     this.value = value
                    //     // 执行成功的回调函数
                    //     this.onFulfilledCallbacks.forEach(fn => fn())
                    // }
                }
                const reject = (value) => {
                    console.log('reject执行:',value)
                }
                // 初始化状态
                func(resolve,reject)
            }
        }
        // 测试代码
        const p = new MyPromise((resolve,reject) => {
            console.log('执行器函数执行')
            resolve('成功')
            reject('失败')
        }) 

状态和原因:
含bug代码
    <h2>状态及原因</h2>
    <script>
        // 1、添加原生Promise状态fulfilled/pending/rejected
        // 2、添加原生Promise原因resolve/reject
        // 3、调整resolve/reject方法
        // 4、状态不可逆
        // 为了方便和规范起见命名MyPromise的状态
        const PENDING = 'pending'
        const FULFILLED = 'fulfilled'
        const REJECTED = 'rejected'
        class MyPromise {
            // 状态初始化
            status = PENDING
            result = undefined
            // 添加构造函数
            constructor(func){
                // 定义resolve和reject方法
                const resolve = (value) => {
                    // 修改状态并记录原因
                    this.status = FULFILLED
                    this.result = value
                }
                const reject = (value) => {
                    // 修改状态并记录原因
                    this.status = REJECTED
                    this.result = value
                }
                // 初始化状态
                func(resolve,reject)
            }
        }
        // 测试代码
        const p = new MyPromise((resolve,reject) => {
            resolve('成功')
            reject('失败')
        })
 
在未添加自定义的状态不可逆时代码有误还是会按照js从上向下执行原则最后改变pending从sucees to fail.

接下来我们开始处理不可逆属性:
 // 定义resolve和reject方法
                const resolve = (result) => {
                    if(this.status === PENDING){
                        // 修改状态并记录结果
                        this.status = FULFILLED
                        this.result = result
                    }
                }
                const reject = (result) => {
                    if(this.status === PENDING){
                        // 修改状态并记录结果
                        this.status = REJECTED
                        this.result = result
                }
                // 初始化状态
                func(resolve,reject)
                } 
then方法:
成功失败回调:
tips:被作为实参传入另一函数,并在该外部函数内被调用,用以来完成某些任务的函数,称为回调函数。
      const PENDING = 'pending'
        const FULFILLED = 'fulfilled'
        const REJECTED = 'rejected'
        class MyPromise {
            // 状态初始化
            // 添加状态
            status = PENDING
            // 添加原因
            result = undefined
            // 添加构造函数
            constructor(func){
                // 定义resolve和reject方法
                const resolve = (result) => {
                    if(this.status === PENDING){
                        // 修改状态并记录结果
                        this.status = FULFILLED
                        this.result = result
                    }
                }
                const reject = (result) => {
                    if(this.status === PENDING){
                        // 修改状态并记录结果
                        this.status = REJECTED
                        this.result = result
                }
            }
                // 初始化状态
                func(resolve,reject)
            }
        then(onFulfilled,onRejected){
            // 根据mdn知道需要判断回调函数是否为函数,如果不是需要处理
            onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value
            onRejected = typeof onRejected === 'function' ? onRejected : reason => {throw reason}
            // 判断状态
            if(this.status === FULFILLED){
                onFulfilled(this.result)
            }
            else if(this.status === REJECTED){
                onRejected(this.result)
            }
        }
        }
        // 测试代码
        const p = new MyPromise((resolve,reject) => {
           // resolve('success')
            reject('fail')
        })
        p.then((res) => {
            console.log('成功回调',res)
        },(err) => {
            console.log('失败抛出错误',err)
        })
 


异步多次调用:
 // 定义常量
        const PENDING = 'pending'
        const FULFILLED = 'fulfilled'
        const REJECTED = 'rejected'
        class MyPromise {
            // 状态初始化
            // 添加状态
            status = PENDING
            // 添加原因
            result = undefined
            // 私有属性handlers
            #handlers = [] //[{onFulfilled,onRejected}...]
            // 添加构造函数
            constructor(func){
                // 定义resolve和reject方法
                const resolve = (result) => {
                    if(this.status === PENDING){
                        // 修改状态并记录结果
                        this.status = FULFILLED
                        this.result = result
                        // 调用成功回调函数
                        this.#handlers.forEach(({onFulfilled}) => {
                            onFulfilled(result)
                        })
                    }
                }
                const reject = (result) => {
                    if(this.status === PENDING){
                        // 修改状态并记录结果
                        this.status = REJECTED
                        this.result = result
                        // 调用失败回调函数
                        this.#handlers.forEach(({onRejected}) => {
                            onRejected(result)
                        })
                }
            }
                // 初始化状态
                func(resolve,reject)
            }
        then(onFulfilled,onRejected){
            // 根据mdn知道需要判断回调函数是否为函数,如果不是需要处理
            onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value
            onRejected = typeof onRejected === 'function' ? onRejected : reason => {throw reason}
            // 判断状态
            // 同步调用
            if(this.status === FULFILLED){
                onFulfilled(this.result)
            }
            else if(this.status === REJECTED){
                onRejected(this.result)
            }//异步和多次调用
            else if(this.status === PENDING){
                // 添加回调函数
               this.#handlers.push({onFulfilled,onRejected})
            }
        }
        }
        // 测试代码
        const p = new MyPromise((resolve,reject) => {
           setTimeout(() => {
               resolve('success')
               reject('fail')
           },1000)
        })
        p.then((res) => {
            console.log('then1',res)
        },(err) => {
            console.log('then1',err)
        })
        p.then((res) => {
            console.log('then2',res)
        },(err) => {
            console.log('then2',err)
        }) 
异步任务:
核心api:
 
   // 异步任务 queueMicrotask
        console.log('start')
        queueMicrotask(() => {
            console.log('queueMicrotask')
        })
        console.log('end')
        // 异步任务 MutationObserver
        // 1、创建观察器,并传入回调函数
        const obs = new MutationObserver(() => {
            console.log('mutationsList')
        })
        // 2、创建元素,并添加监听
        const divNode = document.createElement('div')
        // 参数1dom节点,参数2配置对象childList:true表示监听子节点变化
        obs.observe(divNode,{childList:true})
        // 3、修改元素内容,观察器触发MutationObserver
        divNode.innerText = 'hello' 
函数封装:
// 封装函数分别使用queueMicrotask和MutationObserver setTimeout实现异步任务
        function runAsyncTask(callback){
            // 使用queueMicrotask
            if(typeof queueMicrotask === 'function')
            {
                queueMicrotask(callback)
            }else if (typeof MutationObserver === 'function'){
                // 使用MutationObserver
                const observer = new MutationObserver(callback)
                const nodeDiv = document.createTextNode('div')
                observer.observe(nodeDiv,{childList:true})
                node.innerText = 'hello'
            }else{
            setTimeout((callback) ,0)
            }
        } 
对then中的回调方法增加异步属性
        // 使用封装的异步函数
        then(onFulfilled,onRejected){
            // 根据mdn知道需要判断回调函数是否为函数,如果不是需要处理
            onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value
            onRejected = typeof onRejected === 'function' ? onRejected : reason => {throw reason}
            // 判断状态
            // 同步调用
            if(this.status === FULFILLED){
               runAsyncTask(() => {
                   onFulfilled(this.result)
               })
            }
            else if(this.status === REJECTED){
                runAsyncTask(() => {
                    onRejected(this.result)
                })
            }//异步和多次调用
            else if(this.status === PENDING){
                // 添加回调函数
               this.#handlers.push({
                onFulfilled:()=>{
                    runAsyncTask(() => {
                        onFulfilled(this.result)
                    })
                }
                ,
                onRejected:()=>{
                    runAsyncTask(() => {
                        onRejected(this.result)
                    })
                }
            })
            }
        } 
成功实现异步调用

链式编程:
获取返回值:
处理返回值和处理异常:
使用try-catch进行返回值处理和异常捕获,同时在then中内嵌的promise调用和回调函数的使用完成对上一个then的返回值的捕获和返回。
 // 1、返回新的promise对象 传入的函数是立刻调用的
            const p2 = new MyPromise((resolve,reject)=>{
                 // 判断状态
            // 同步调用
            if(this.status === FULFILLED){
               runAsyncTask(() => {
                // 2、获取返回值
                 try {
                    const x = onFulfilled(this.result)
                  // 2.1处理返回值
                  resolve(x)
                 } catch (error) {
                    reject(error)
                 }
               })
            }
            else if(this.status === REJECTED){
                runAsyncTask(() => {
                    onRejected(this.result)
                })
            }//异步和多次调用
            else if(this.status === PENDING){
                // 添加回调函数
               this.#handlers.push({
                onFulfilled:()=>{
                    runAsyncTask(() => {
                        onFulfilled(this.result)
                    })
                }
                ,
                onRejected:()=>{
                    runAsyncTask(() => {
                        onRejected(this.result)
                    })
                }
            })
            }
            })
           return p2 

处理返回promise:
tips:instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。
x为返回的promise实例
runAsyncTask(() => {
                // 2、获取返回值
                 try {
                   const x = onFulfilled(this.result)
                   if(x instanceof MyPromise){
                       x.then(res => resolve(res),err => reject(err))
                   }
                   else{resolve(x)}
                 } catch (error) {
                    reject(error)
                 }
               })
// 测试代码
        // console.log('start')
        const p = new MyPromise((resolve,reject) => {
            resolve(1)  
            //reject('fail')
        })
        p.then((res)=>{
            return new MyPromise((resolve,reject) => {
                resolve(2)
            })
        }).then((res) => {
           console.log('p2',res)
        },(err) => {
            console.log('p2',err)
        }) 


获取重复调用:
利用原生Promise报错模仿写自己的Promise返回相同值(Promise)的报错
Chaining cycle detected for promise #<Promise> 
 // 处理重复引用
            const p2 = new MyPromise((resolve,reject)=>{
            if(this.status === FULFILLED){
               runAsyncTask(() => { 
                 try {
                   const x = onFulfilled(this.result)
                        // 判断是否重复
                    if(x===p2)
                    {
                        // 抛出异常Chaining cycle detected for promise #<Promise>
                        throw new TypeError('Chaining cycle detected for promise #<Promise>')
                    }
                   if(x instanceof MyPromise){
                       x.then(res => resolve(res),err => reject(err))
                   }
                   else{resolve(x)}
                 } catch (error) {
                    reject(error)
                 }
               }) 
成功捕获错误!


对于reject同理,同样需要处理返回值和异常、处理返回promise、获取重复调用四个步骤,用于代码需要重复调用,所以我们将其封装成函数以进行复用
        // 抽取函数
        function resolvePromise(p2,x,resolve,reject){
            if(x === p2){
                throw new TypeError('Chaining cycle detected for promise #<Promise>')
            }
            if(x instanceof MyPromise){
                x.then(res => resolve(res),err => reject(err))
            }else{
                resolve(x)
            }
        } 
功能正常!

作为中立状态的pending也必不可少,同样需要处理返回值和异常、处理返回promise、获取重复调用四个步骤。
 // 添加回调函数
               this.#handlers.push({
                onFulfilled:()=>{
                    runAsyncTask(() => {
                        // 1、处理异常
                       try {
                        // 2、获取返回值
                        const x =  onFulfilled(this.result)
                        // 3、调用函数
                        resolvePromise(p2,x,resolve,reject)
                       } catch (error) {
                        reject(error)
                       }
                    })
                }
                ,
                onRejected:()=>{
                    runAsyncTask(() => {
                        // 1、处理异常
                        try {
                        // 获取返回值
                        const x = onRejected(this.result)
                        resolvePromise(p2,x,resolve,reject)
                        } catch (error) {
                            reject(error)
                        }
                    })
                }
            }) 
仍可成功获取。
实例方法:
.catch()
Promise 实例的 catch() 方法用于注册一个在 promise 被拒绝时调用的函数。它会立即返回一个等效的 Promise 对象,这可以允许你链式调用其他 promise 的方法。此方法是 Promise.prototype.then(undefined, onRejected) 的一种简写形式。
根据文档在then方法中添加已有catch方法,却发现无法调用reject中捕获异常功能,而是在调试throw error使用浏览器报错,故在自己定义的reject方法中使用try catch 捕获错误。
  const reject = (result) => {
                    if(this.status === PENDING){
                        // 修改状态并记录结果
                        this.status = REJECTED
                        this.result = result
                        // 调用失败回调函数
                        this.#handlers.forEach(({onRejected}) => {
                            onRejected(result)
                        })
                }
            }
                // 处理异常
                try {
                    func(resolve,reject)  
                } catch (error) {
                    reject(error)
                }
  then(onFulfilled,onRejected){
            // 根据mdn知道需要判断回调函数是否为函数,如果不是需要处理
            onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value
            onRejected = typeof onRejected === 'function' ? onRejected : reason => {throw reason}
            // 处理重复引用
            const p2 = new MyPromise((resolve,reject)=>{
            if(this.status === FULFILLED){
               runAsyncTask(() => { 
                 try {
                   const x = onFulfilled(this.result)
                   resolvePromise(p2,x,resolve,reject)
                //         // 判断是否重复
                //     if(x===p2)
                //     {
                //         // 抛出异常Chaining cycle detected for promise #<Promise>
                //         throw new TypeError('Chaining cycle detected for promise #<Promise>')
                //     }
                //    if(x instanceof MyPromise){
                //        x.then(res => resolve(res),err => reject(err))
                //    }
                //    else{resolve(x)}
                 } catch (error) {
                    reject(error)
                 }
               })
            }
            else if(this.status === REJECTED){
                runAsyncTask(() => {
                    try {
                        const x = onRejected(this.result)
                        resolvePromise(p2,x,resolve,reject)
                    } catch (error) {
                        reject(error)
                    }
                })
            }//异步和多次调用
            else if(this.status === PENDING){
                // 添加回调函数
               this.#handlers.push({
                onFulfilled:()=>{
                    runAsyncTask(() => {
                        // 1、处理异常
                       try {
                        // 2、获取返回值
                        const x =  onFulfilled(this.result)
                        // 3、调用函数
                        resolvePromise(p2,x,resolve,reject)
                       } catch (error) {
                        reject(error)
                       }
                    })
                }
                ,
                onRejected:()=>{
                    runAsyncTask(() => {
                        // 1、处理异常
                        try {
                        // 获取返回值
                        const x = onRejected(this.result)
                        resolvePromise(p2,x,resolve,reject)
                        } catch (error) {
                            reject(error)
                        }
                      })
                    }
                  })
               }
            })
           return p2
        }
        
            catch(onRejected){
                return this.then(undefined,onRejected)
            }
        }
// 测试手写
        const p = new MyPromise((resolve,reject) => {
           // reject('fail')
            throw 'error!'
        })
        p.then(res=>{
            console.log('res:',res)
        }).catch(err => {
            console.log('err:',err)
        })
 

.finally
Promise 实例的 finally() 方法用于注册一个在 promise 敲定(兑现或拒绝)时调用的函数。它会立即返回一个等效的 Promise 对象,这可以允许你链式调用其他 promise 方法。
无论错误还是成功都不会影响调用.finally时的输出。
finally(onFinally){
                return this.then(onFinally,onFinally)
            } 
静态方法:
.resolve()
Promise.resolve() 静态方法将给定的值转换为一个 Promise。如果该值本身就是一个 Promise,那么该 Promise 将被返回;如果该值是一个 thenable 对象,Promise.resolve() 将调用其 then() 方法及其两个回调函数;否则,返回的 Promise 将会以该值兑现。
 // 添加静态方法
            static resolve(value){
                if(value instanceof MyPromise){
                    return value
                }
                return new MyPromise((resolve,reject) => {
                    resolve(value)
                })
            }
      
 // 测试手写
        MyPromise.resolve(new MyPromise((resolve,reject) => {
            //resolve(1)
            //reject('fail')
            //throw 'error'
        })).then(res => {
            console.log('res:',res)
        },err=>{
            console.log('err:',err)
        })
        MyPromise.resolve('ian').then(res=>{
            console.log('res:',res)
        }) 

.reject()
Promise.reject() 静态方法返回一个已拒绝(rejected)的 Promise 对象,拒绝原因为给定的参数。
static reject(value){
                return new MyPromise((undefined,reject) => {
                    reject(value)
                })
            } 
.race()
Promise.race() 静态方法接受一个 promise 可迭代对象作为输入,并返回一个 Promise。这个返回的 promise 会随着第一个 promise 的敲定而敲定。
static race(promises){
               // 1、返回Promise对象
                return new MyPromise((resolve,reject)=>{
                    // 2、判断是否为数组
                    if(!Array.isArray(promises)){
                       return reject(new TypeError('You must pass an array')) 
                    }
                    // 3、等待第一个敲定
                    promises.forEach(p=>{
                        //p.then
                        MyPromise.resolve(p).then(res => {resolve(res)},err => {reject(err)})
                    })
                }) 
            } 
.all()
Promise.all() 静态方法接受一个 Promise 可迭代对象作为输入,并返回一个 Promise。当所有输入的 Promise 都被兑现时,返回的 Promise 也将被兑现(即使传入的是一个空的可迭代对象),并返回一个包含所有兑现值的数组。如果输入的任何 Promise 被拒绝,则返回的 Promise 将被拒绝,并带有第一个被拒绝的原因。
、
static all(promises){
                // 1、返回Promise对象
                return new MyPromise((resolve,reject)=>{
                    // 2、判断是否为数组
                    if(!Array.isArray(promises)){
                        return reject(new TypeError('Argument is not iterable'))
                    }
                    // 3、空数组直接兑现
                    promises.length === 0 && resolve(promises)
                    // 4、处理全部兑现
                    //     4.1、记录结果:使用索引来记录,保证结果的顺序和Promise数组的顺序一致
                    //     4.2、判断是否全部兑现:通过兑现的次数来判断,保证可以获取道德所有结果
                    const results = [] // 记录结果
                    let count = 0 // 记录兑现次数
                    promises.forEach((p,index)=>{
                        MyPromise.resolve(p).then(
                            res => {
                                results[index] = res
                                // 判断是否全部兑现
                                count++
                                count === promises.length && resolve(results)
                            },
                            err => {
                                // 有一个失败则全部失败
                                reject(err)
                            }
                        )
                    })
                })
            } 
![]()
.allSettled()
Promise.allSettled() 静态方法将一个 Promise 可迭代对象作为输入,并返回一个单独的 Promise。当所有输入的 Promise 都已敲定时(包括传入空的可迭代对象时),返回的 Promise 将被兑现,并带有描述每个 Promise 结果的对象数组。


无论是resolve还是reject都属于promise的pending敲定,使用resolve!
  
  static allSettled(promises){
                // 1、返回Promise对象
                return new MyPromise((resolve,reject)=>{
                    // 2、判断是否为数组
                    if(!Array.isArray(promises)){
                        return reject(new TypeError('Argument is not iterable'))
                    }
                    // 3、空数组直接兑现
                    promises.length === 0 && resolve(promises)
                    // 4、处理全部兑现
                    //     4.1、记录结果:使用索引来记录,保证结果的顺序和Promise数组的顺序一致
                    const results = [] // 记录结果
                    let count = 0 // 记录兑现次数
                    promises.forEach((p,index)=> {
                        MyPromise.resolve(p).then(
                         res =>{
                            // 4.2、处理兑现{status: FULFILLED,value: res}
                            results[index] = {status: FULFILLED,value: res}
                            count++
                            count === promises.length && resolve(results)
                         },err=>{
                            // 4.3、处理拒绝{status: REJECTED,reason: err}
                            results[index] = {status: REJECTED,reason: err}
                            count++
                            count === promises.length && resolve(results)
                         }
                        )
                    })
                })
            }
// 测试手写
        const p1 = MyPromise.resolve(1)
        const p2 = 2
        const p3 = new MyPromise((resolve,reject) => {
            setTimeout(() => {
               // resolve(3)
                reject('fail')
            },1000)
        })
        MyPromise.allSettled([p1,p2,p3]).then(res => {
            console.log('res:',res)
        },err => {
            console.log('err:',err)
        }) 
 
.any()
Promise.any() 静态方法将一个 Promise 可迭代对象作为输入,并返回一个 Promise。当输入的任何一个 Promise 兑现时,这个返回的 Promise 将会兑现,并返回第一个兑现的值。当所有输入 Promise 都被拒绝(包括传递了空的可迭代对象)时,它会以一个包含拒绝原因数组的 AggregateError 拒绝。


AggregateError 对象代表了包装了多个错误对象的单个错误对象。当一个操作需要报告多个错误时,例如 Promise.any(),当传递给它的所有承诺都被拒绝时,就会抛出该错误。
AggregateError 是 Error 的子类。
            static any(promises){
                // 1、返回Promise对象
                return new MyPromise((resolve,reject)=>{
                    // 2、判断是否为数组
                    if(!Array.isArray(promises)){
                        return reject(new TypeError('Argument is not iterable'))
                    }
                    // 3、空数组直接拒绝
                    promises.length === 0 && reject(new AggregateError(promises,'All promises were rejected'))
                    // 4、处理第一个兑现
                    //     4.1、记录结果:使用索引来记录,保证结果的顺序和Promise数组的顺序一致
                    //     4.2、判断是否全部兑现:通过兑现的次数来判断,保证可以获取道德所有结果
                    const errors = [] // 记录结果
                    let count = 0 // 记录兑现次数
                    promises.forEach((p,index)=>{
                        MyPromise.resolve(p).then(
                            // 第一个兑现
                            res => {
                                resolve(res)
                            },
                            err => {
                                // 全部拒绝
                                errors[index] = err
                                count++
                                count === promises.length && reject(new AggregateError(errors,'All promises were rejected'))
                            }
                        )
                    })
                })
            }
 // 测试手写
        const p1 = new MyPromise((resolve,reject) => {
            setTimeout(() => {
                //resolve(1)
                reject(1)
            },2000)
        })
        const p2 = MyPromise.reject(2)
        const p3 = new MyPromise((resolve,reject) => {
            setTimeout(() => {
                //resolve(3)
                reject(3)
            },1000)
        })
       // MyPromise.any([]).then(res => {
        //MyPromise.any().then(res => {
        MyPromise.any([p1,p2,p3]).then(res => {
            console.log('res:',res)
        },err => {
            console.dir(err)
        })
 
                



















