手写promise异步状态修改then方法返回来的结果

简介: 手写promise异步状态修改then方法返回来的结果

看看下面这一段代码返回来的是什么???


<body>
    <script type="text/javascript">
        let p = new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('ok');
            }, 1000)
        })
        const res=p.then(res => {
            console.log(res)
        }, err => {
            console.log(err)
        })
        // 根据promise返回来的结果规律,
        // 由于我什么都没有写,返回的应该是undefined
        // 它返回的的是非Promise类型的数据,如undefined; 数字,字符串。
        // 那么 result就是一个成功的Promise
        console.log( 'res', res )
    </script>
</body>



1425695-20210913223324342-488812731.png


我们现在写的promise


<script src="./Promise.js"></script>
<body>
    <script type="text/javascript">
        let p = new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('ok');
            }, 1000)
        })
        const res=p.then(res => {
            console.log(res)
        }, err => {
            console.log(err)
        })
        console.log( 'res', res )
    </script>
</body>


结果


{
    PromiseStatus:"pending"
    PromiseValue:null
}


为啥是padding


当我们的代码从上往下执行的时候,


会走进

if (this.PromiseStatus === "pending") {
    // 这个是保存回调函数
    this.callBack.push({
    onResolve: onResolve,
    onReject: onReject,
    });
}

这里;


我们知道这里并没有去调用 resolve, reject


所以返回来的状态一定是一个padding


如何处理这个问题


const self=this; // new add
if (this.PromiseStatus === "pending") {
    // 这个是保存回调函数  new add
    this.callBack.push({
        // 执行成功的回调函数,改变里面的状态
        // 下面这些都是根据promise返回结果的结论来写的
        onResolve: function () {
            let result = onResolve(self.PromiseStatus)
            // 判断是否是promise,根据是否是promise返回不同的状态
            if (result instanceof Promise) {
                // 如果是一个promise就可以去调用then方法
                result.then(s => {
                    resolve(s)
                }, e => {
                    reject(e)
                })
            } else {
                // 如果不是promise直接返回成功
                resolve(result)
            }
        },
        onReject: function () {
            let result = onReject(self.PromiseStatus)
            // 判断是否是promise,根据是否是promise返回不同的状态
            if (result instanceof Promise) {
                // 如果是一个promise就可以去调用then方法
                result.then(s => {
                    resolve(s)
                }, e => {
                    reject(e)
                })
            } else {
                // 如果不是promise直接返回成功
                resolve(result)
            }
        }
    });
}


现在虽然可以返回正常的结果和状态,但是抛出异常是有问题的哈,使用try catch


完整版本


function Promise(executor) {
  const self = this;
  function resolve(data) {
    // 如果状态发生改变就直接返回(为了让Promise的状态只发生一次改变);
    if (self.PromiseStatus !== "pending") return;
    self.PromiseStatus = "resolved";
    self.PromiseValue = data;
    // 调用成功的回调函数进行遍历
    self.callBack.forEach((item) => {
      item.onResolve(data);
    });
  }
  // 同样声明成为一个函数;修改状态
  function reject(err) {
    // 如果状态发生改变就直接返回(为了让Promise的状态只发生一次改变);
    if (self.PromiseStatus !== "pending") return;
    self.PromiseStatus = "rejected";
    self.PromiseValue = err;
    // 调用失败的回调函数数进行遍历
    self.callBack.forEach((item) => {
      item.onReject(err);
    });
  }
  this.PromiseStatus = "pending";
  this.PromiseValue = null;
  // 声明属性 new  add
  this.callBack = [];
  // 对异常进行处理;使用try catch
  try {
    executor(resolve, reject);
  } catch (err) {
    reject(err);
  }
}
// 自定义封装then方法执行回调
Promise.prototype.then = function (onResolve, onReject) {
    // new add注意this的指向
    const self = this;
    // 返回一个promise对象
    return new Promise((resolve,reject)=>{
        if (this.PromiseStatus === "resolved") {
            try{
                let chenggong= onResolve(this.PromiseValue);
                if(chenggong instanceof Promise){
                    // 如果你是一个Promise,那么可以去调用这个then方法
                    chenggong.then(v=>{
                        resolve(v);
                    },r=>{
                        reject(r);
                    })
                }else{
                    // 不是Promise类型的对象
                    // 结果的对象状态【成功】
                    resolve(chenggong)
                }
            }catch(e){
                reject(e);
            }
            // 获取回调函数的执行结果
        }
        if (this.PromiseStatus === "rejected") {
            onReject(this.PromiseValue);
        }
        // 如果是pending的状态
        if (this.PromiseStatus === "pending") {
           // 这个是保存回调函数  new add
            this.callBack.push({
                // 执行成功的回调函数,改变里面的状态
                // 下面这些都是根据promise返回结果的结论来写的
                onResolve: function () {
                    //对抛出的异常进行处理哈
                    try {
                        let result = onResolve(self.PromiseStatus)
                        // 判断是否是promise,根据是否是promise返回不同的状态
                        if (result instanceof Promise) {
                            // 如果是一个promise就可以去调用then方法
                            result.then(s => {
                                resolve(s)
                            }, e => {
                                reject(e)
                            })
                        } else {
                            // 如果不是promise直接返回成功
                            resolve(result)
                        }
                    } catch (error) {
                         reject(error)
                    }
                },
                onReject: function () {
                    //对抛出的异常进行处理哈
                    try {
                        let result = onReject(self.PromiseStatus)
                        // 判断是否是promise,根据是否是promise返回不同的状态
                        if (result instanceof Promise) {
                            // 如果是一个promise就可以去调用then方法
                            result.then(s => {
                                resolve(s)
                            }, e => {
                                reject(e)
                            })
                        } else {
                            // 如果不是promise直接返回成功
                            resolve(result)
                        }
                    } catch (error) {
                        reject(error)
                    }
                }
            });
        }
    })
};
相关文章
|
10月前
|
前端开发
在什么场景下适合使用 Promise.race() 方法?
在什么场景下适合使用 Promise.race() 方法?
663 167
|
10月前
|
前端开发
如何使用 Promise 的 all 方法?
如何使用 Promise 的 all 方法?
916 162
|
前端开发 索引
Promise.all() 方法的参数可以是什么类型?
综上所述,`Promise.all()` 方法的参数类型较为灵活,但无论使用哪种类型的可迭代对象作为参数,其核心的异步操作处理逻辑和成功失败的判断机制都是一致的,都是为了方便地处理多个异步操作的并发执行和结果汇总。
511 155
|
前端开发 数据处理
如何使用 Promise.all() 处理异步并发操作?
使用 `Promise.all()` 可以方便地处理多个异步并发操作,提高代码的执行效率和可读性,同时通过统一的 `.catch()` 方法能够有效地处理异步操作中的错误,确保程序的稳定性。
1012 155
|
前端开发
如何在不使用catch方法的情况下处理Promise.reject()抛出的错误?
如何在不使用catch方法的情况下处理Promise.reject()抛出的错误?
630 155
|
前端开发
在Promise链中是否可以多次使用catch方法?
在Promise链中是否可以多次使用catch方法?
480 154
|
前端开发
Promise有哪些常用的方法?
Promise有哪些常用的方法?
485 154
|
前端开发 JavaScript
除了使用Polyfill,还有其他解决Promise.allSettled()兼容性问题的方法吗?
除了使用Polyfill,还有其他解决Promise.allSettled()兼容性问题的方法吗?
533 179