手写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)
                    }
                }
            });
        }
    })
};
相关文章
|
1月前
|
前端开发 JavaScript
如何使用 Promise 处理异步并发操作?
通过使用 `Promise.all()` 和 `Promise.race()` 方法,可以灵活地处理各种异步并发操作,根据不同的业务需求选择合适的方法来提高代码的性能和效率,同时也使异步代码的逻辑更加清晰和易于维护。
|
1月前
|
前端开发 索引
Promise.all() 方法的参数可以是什么类型?
综上所述,`Promise.all()` 方法的参数类型较为灵活,但无论使用哪种类型的可迭代对象作为参数,其核心的异步操作处理逻辑和成功失败的判断机制都是一致的,都是为了方便地处理多个异步操作的并发执行和结果汇总。
|
1月前
|
存储 前端开发
除了 Promise.all(),还有哪些方法可以处理异步并发操作?
在上述示例中,`concurrentPromises` 函数接受一个Promise数组和最大并发数作为参数,通过手动控制并发执行的Promise数量,实现了对异步操作的并发控制,并在所有Promise完成后返回结果数组。
|
1月前
|
前端开发 数据处理
如何使用 Promise.all() 处理异步并发操作?
使用 `Promise.all()` 可以方便地处理多个异步并发操作,提高代码的执行效率和可读性,同时通过统一的 `.catch()` 方法能够有效地处理异步操作中的错误,确保程序的稳定性。
|
26天前
|
前端开发
Promise.allSettled()方法和Promise.race()方法有什么区别?
`Promise.allSettled()` 提供了一种更全面、更详细的方式来处理多个 `Promise`,而 `Promise.race()` 则更强调速度和竞争。我们需要根据具体的需求来选择使用哪种方法。
|
1月前
|
前端开发
`Promise.all()`方法在处理数组形式参数时的执行机制
Promise.all()` 提供了一种方便的方式来同时处理多个异步操作,并在它们都完成后获取到所有的结果,使得我们能够更高效地进行异步任务的组合和处理。
|
1月前
|
前端开发
`Promise.allSettled()`方法与`Promise.all()`方法有何不同?
`Promise.allSettled()` 提供了一种更灵活和全面的方式来处理多个 `Promise`,使得我们能够更好地应对各种异步操作的情况,尤其是需要详细了解每个 `Promise` 结果的场景。
|
26天前
|
监控 调度
在什么情况下应该使用 Promise.allSettled() 方法?
总的来说,`Promise.allSettled()` 为我们处理多个异步任务提供了一种更灵活、更全面的方式,使我们能够更好地应对各种复杂的情况,确保在获取到所有任务结果的同时,能够进行更有效的后续处理和决策。
|
1月前
|
前端开发 索引
Promise.all() 方法的参数可以是哪些数据类型?
`Promise.all()` 方法的参数具有很大的灵活性,可以适应多种不同的场景和需求,方便地处理多个异步操作的并发执行和结果汇总。
|
1月前
|
前端开发 JavaScript 开发者
用 Promise 处理异步操作的优势是什么?
综上所述,使用Promise处理异步操作能够有效地解决传统回调函数带来的诸多问题,提高代码的质量、可读性、可维护性和可扩展性,是JavaScript中进行异步编程的重要工具和技术。