经典Promise面试题----手写Promise详细步骤(三)

手写Promise封装继续行进----实现then方法的结构功能!
按照步骤进行,逻辑思路很简单易实现!
前文链接导航:

功能1:搭建Promise结构,实现关键resolve、reject功能
功能2:实现throw抛出异常以及Promise对象状态单次更改功能

本文在前两篇的实现基础上继续封装Promise其他功能
	1then()方法执行回调的实现
  1. 首先:实例化对象中调用then方法
<script src="./Promise.js"></script>
<body>
  <script>
    let p = new Promise((resolve, reject) => {

     // reject('error');
      resolve('OK');
      // 抛出异常
      // throw "error"
    })
    console.log(p)
    // 实例调用then方法
    p.then(value => {
      console.log(value);//成功用log输出
    }, reason => {
      console.warn(reason);//失败用warn输出
    })
  </script>

  1. 注释掉script标签引用,查看内置Promise的表现,明确自定义封装预期结果,结果如下:
//注释掉下列代码,查看内置表现
<script src="./Promise.js"></script>

在这里插入图片描述

  1. 恢复script标签引入,因为我们没有进行相应的封装,没有调用then方法,所以还不能实现上述功能,由于同步执行,所以需要在Promise.then()方法中调用回调函数,逻辑结构如下:

在这里插入图片描述
代码结构为:

// 添加then方法
Promise.prototype.then=function(onResolved,onRejectd){
  // 调用回调函数,这里不能直接调用,因为promise的状态是不一定的
  if(){
      // 成功调用onResolved 
    onResolved();
  }
  if(){
      // 失败调用onRejected
    onRejectd();
  }
}
分析判断条件:
我们知道成功和失败的不同状态会回调不同的函数,那么成功和失败的判断条件是什么呢?
	----应该是上述Promise实例对象中声明的PromiseState这个属性(不懂请导航到前两篇文章...

具体代码如下:

// 添加then方法
Promise.prototype.then=function(onResolved,onRejectd){
  // 调用回调函数,这里不能直接调用,因为promise的状态是不一定的
  if(this.PromiseState === 'fulfilled'){
      // 成功调用onResolved 
    onResolved();
  }
  if(this.PromiseState === 'rejected'){
      // 失败调用onRejected
    onRejectd();
  }
}

代码中的this指向问题解释:

   1:then方法是由p这个Promise实例调用的,所以在这个对象中,this就是指向实例对象p的
   2:所以this.PromiseState获取的就是p这个实例的PromiseState属性

4:继续向下发现问题,逻辑关系展示:
在这里插入图片描述

上图问题描述:
	1:  实例p.then()中的回调函数声明时是有形参的(value或者reason)
	2:   这个函数在调用时是传给了.then()方法中的onResolved实参
	3:但是按照上述代码,调用时并没有给传递相应参数
	4:这个参数是保存了上述状态更改的具体值,也就是之前声明的PromiseResult这个属性
	5:于是继续完善代码如下:
// 添加then方法
Promise.prototype.then=function(onResolved,onRejectd){
  // 调用回调函数,这里不能直接调用,因为promise的状态是不一定的
  if(this.PromiseState === 'fulfilled'){
      // 成功调用onResolved 
    onResolved(this.PromiseResult);
  }
  if(this.PromiseState === 'rejected'){
      // 失败调用onRejected
    onRejectd(this.PromiseReslut);
  }
}

逻辑分析:
在这里插入图片描述
代码执行结果:

当然可以验证reject 以及 throw 改变promise状态,同时调用.then方法,这里暂不展示,大家可以自行验证。

在这里插入图片描述
至此,我们队then方法中回调的执行有了一个完整的实现!但是…

注意:
	1:以上三节代码都是执行器中的函数为同步执行,即通过resolve('  OK '),直接改变Promise对象的状态,而不是异步改变的。
	2:在接下来的封装中,考虑执行器中使用异步方式 :
	 	let p = new Promise((resolve, reject) => {
     		 // 执行器中异步执行改变状态
     		 setTimeout(()=>{
       			 resolve('OK');
    		  },1000)
	     // 执行器中同步执行改变状态
	      // reject('error');
	      // resolve('OK');
	      // 抛出异常
	      // throw "error"
    })
    3:使用setTimeout()也只是用定时器做一个模拟,方便实现
      而在实际中,可能是一个文件的IO,数据库的IO,也可能是一个网络请求的IO,
      总之是异步的,并不是立刻改变对象状态的
    4:对于这种异步的,要求也是能够成功执行回调的,显然我们目前封装的代码还不可以实现。
    

总结:这里放上截止目前手写Promise的完整代码,包含以往三部分的全部功能,如下:

全部功能:
	1:搭建自定义Promise结构,实现关键resolve、reject功能。
	2:实现throw抛出异常改变对象状态
	3:确保Promise对象状态只能更改一次
	4:实现关键then方法的调用功能
index.html中全部代码:
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Promise封装</title>
</head>
<script src="./Promise.js"></script>
<body>
  <script>
    let p = new Promise((resolve, reject) => {
      // 执行器中异步执行改变状态
      setTimeout(()=>{
        resolve('OK');
      },1000)
      // 执行器中同步执行改变状态
      // reject('error');
      // resolve('OK');
      // 抛出异常
      // throw "error"
    })
    // console.log(p)
    // 实例调用then方法
    p.then(value => {
      console.log(value);//成功用log输出
    }, reason => {
      console.warn(reason);//失败用warn输出
    })
  </script>
</body>
</html>
Promise.js中全部代码:
// 声明构造函数
function Promise(executor){
  // 添加属性,以便下面修改
  this.PromiseState="pendding";
  this.PromiseResult=null;
  // 保存实例对象的 this 的值
  const self=this;
  // resolve函数
  function resolve(data){
    // 判断状态
    if(self.PromiseState !== 'pendding') return;
    // 1.修改对象的状态
    self.PromiseState="fulfilled";//和resolved一样的含义,都表示成功
    // 2.设置对象的结果值
    self.PromiseResult=data;
  }
  // reject函数
  function reject(data){
    // 判断状态
    if(self.PromiseState !== 'pendding') return;
    // 1.修改对象的状态
    self.PromiseState="rejected";
    // 2.设置对象的结果值
    self.PromiseResult=data;
  }
  try{
    // 同步调用 -- 执行器函数
    executor(resolve,reject);
  }catch(err){
    // 修改 promise 对象的状态为失败
    reject(err);
  }
}

// 添加then方法
Promise.prototype.then=function(onResolved,onRejectd){
  // 调用回调函数,这里不能直接调用,因为promise的状态是不一定的
  if(this.PromiseState === 'fulfilled'){
      // 成功调用onResolved 
    onResolved(this.PromiseResult);
  }
  if(this.PromiseState === 'rejected'){
      // 失败调用onRejected
    onRejectd(this.PromiseReslut);
  }
}

对应的代码在每一个小节中都有详细的介绍,务必注意搞清逻辑关系,实现起来就会很灵活轻松! 后续异步执行功能继续更新封装,敬请期待,感谢观看!

在前端面试中,手写Promise是一个常见的考点。Promise是一种用于处理异步操作的技术,可以简化异步代码的编写和管理。以下是手写Promise的基本步骤: 1. 创建Promise构造函数:首先,你需要声明一个Promise构造函数,用于接收一个执行器函数作为参数。执行器函数中包含了异步操作的逻辑。 2. 实现Promise内部的状态管理:Promise种状态,分别是pending(进行中)、fulfilled(已成功)和rejected(已失败)。在构造函数中,你可以使用一个内部变量来管理Promise的状态。初始状态为pending。 3. 实现resolve和reject方法:在构造函数中,你需要定义resolve和reject方法,用于改变Promise的状态。resolve方法用于将Promise从pending状态改变为fulfilled状态,reject方法用于将Promise从pending状态改变为rejected状态。这两个方法通常会在异步操作成功或失败时被调用。 4. 添加then方法:在Promise的原型对象上添加then方法,用于处理Promise状态改变后的回调函数。then方法接收两个参数,分别是onResolved和onRejected,它们分别代表异步操作成功和失败时的回调函数。 5. 执行器函数中调用resolve和reject方法:在构造函数中的执行器函数中,你需要调用resolve方法将Promise的状态改变为fulfilled,并传递异步操作的结果;或者调用reject方法将Promise的状态改变为rejected,并传递失败的原因。 6. 执行then方法中的回调函数:当Promise的状态被改变后,then方法中的回调函数将会被执行。如果Promise的状态是fulfilled,则执行onResolved回调函数;如果Promise的状态是rejected,则执行onRejected回调函数。 通过上述步骤,你可以手写一个基本的Promise实现。这样在面试中,当你被要求手写Promise的时候,你就可以按照这个步骤来进行代码的编写。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [前端面试大厂手写源码系列(上)](https://download.csdn.net/download/weixin_38739950/14045217)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [面试准备之手写Promise](https://blog.csdn.net/weixin_49172439/article/details/124514197)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [经典Promise面试题----手写Promise详细步骤(一)](https://blog.csdn.net/czj1049561601/article/details/113829149)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值