手写Promise简单版

首先应该了解,Promise具有哪些特点,以此梳理出需要实现的需求点,这里先实现一些比较基础的方法,主要有以下几点:

  1. 实现resolve和reject回调
  2. 状态不可变
  3. 实现throw抛出异常
  4. 实现then方法
  5. 实现then的链式调用
  6. 微任务

实现resolve和reject回调

先来看一段代码

	 let p1 = new Promise((resolve, reject) => {
	        resolve('success');
	 })
	 console.log(p1);
	 
	 let p2 = new Promise((resolve, reject) => {
	        reject('fail');
	 })
	 console.log(p2);

控制台输出:
在这里插入图片描述

从上面两段代码可以看出resolve()执行的是成功的回调,并且执行resolve方法后Promise状态会由pending变为fulfilled,相反,reject()执行的是失败的回调,执行reject方法后Promise状态会由pending变为rejected,知道了这一点就可以开始撸代码啦~

    class myPromise {
        constructor(excutor) {
            //初始化
            this.promiseState = 'pending';
            this.promiseResult = null;
            this.resolve = this.resolve.bind(this);
            this.reject = this.reject.bind(this);
            excutor(this.resolve, this.reject);
        }
        resolve(val) {
            this.promiseState = 'fulfilled';
            this.promiseResult = val;
        }
        reject(reason) {
            this.promiseState = 'rejected';
            this.promiseResult = reason;
        }

    }
	
	let p = new myPromise((resolve, reject) => {
		resolve('success')
	})
	console.log(p);

运行一下代码:

在这里插入图片描述

状态不可变

上面已经初步实现了resolve和reject回调,也进行了代码测试,那么如果把代码改成下面那样,会发生什么事情呢?

    let p = new myPromise((resolve, reject) => {
        resolve('success');
        reject('fail');
    })

输出结果:
在这里插入图片描述
从上面的代码运行结果看,myPromise状态为rejected,也就是说myPromise的状态是可以改变的,那么怎样才能实现状态不可变呢?
很简单,在执行resolve和reject方法前加个判断

    class myPromise {
        constructor(excutor) {
            //初始化
            this.promiseState = 'pending';
            this.promiseResult = null;
            this.resolve = this.resolve.bind(this);
            this.reject = this.reject.bind(this);
            excutor(this.resolve, this.reject);
        }
        resolve(val) {
            if (this.promiseState !== 'pending') return;
            this.promiseState = 'fulfilled';
            this.promiseResult = val;
        }
        reject(reason) {
            if (this.promiseState !== 'pending') return;
            this.promiseState = 'rejected';
            this.promiseResult = reason;
        }

    }

再次执行上述代码:
在这里插入图片描述

实现throw抛出异常

    let p = new Promise((resolve, reject) => {
        throw ('fail')
    })
    console.log(p);

上面的代码会输出什么呢?
在这里插入图片描述

可以看出,Promise中抛出一个异常,相当于执行了Promise中的reject方法

下面就来实现一下

	constructor(excutor) {
	    //初始化
	     this.promiseState = 'pending';
	     this.promiseResult = null;
	     this.resolve = this.resolve.bind(this);
	     this.reject = this.reject.bind(this);
	     try {
	         excutor(this.resolve, this.reject);
	     } catch (err) {
	         this.reject(err);
	     }
	 }

将代码改成上面那样,通过try…catch捕捉异常,然后调用reject方法返回,最后验证一下代码:

	 let p = new myPromise((resolve, reject) => {
	        throw ('fail');
	  })
	  console.log(p);

在这里插入图片描述

实现then方法

then方法接收两个回调,一个是成功回调,一个是失败回调。当Promise状态为fulfilled时,执行成功回调,rejected时执行失败回调。

	 then(onFulfilled, onRejected) {
	    if (this.promiseState === 'fulfilled') {
	         onFulfilled(this.promiseResult);
	     }
	
	     if (this.promiseState === 'rejected') {
	         onRejected(this.promiseResult);
	     }
	 }

验证一下代码:

   let p = new myPromise((resolve, reject) => {
        resolve('success');
    })

    p.then(res => {
        console.log("res输出:", res);
    })

在这里插入图片描述

then的链式调用

	//链式调用
    let p3 = new Promise((resolve, reject) => {
      	resolve(10);
    }).then(res => {
        return res * 2
    }).then(res => {
        console.log('res:', res);
    }, err => {
        console.log('err:', err);
    })  // 输出20
	
	//链式调用
    let p3 = new Promise((resolve, reject) => {
      	resolve(10);
    }).then(res => {
        return new Promise((resolve, reject) => {
            reject('fail');
        })
    }).then(res => {
        console.log('res:', res);
    }, err => {
        console.log('err:', err);
    })  // 输出fail

从上面的代码中可以总结出:

  1. then可以链式调用,即then方法本身会返回一个新的Promise
  2. 上一个then的返回值会影响下一个then的执行结果:
    当返回值是一个Promise对象,返回值为成功,则then执行成功
    当返回值是一个Promise对象,返回值为失败,则then执行失败
    当返回值不是一个Promise对象,返回值为成功,then执行成功

微任务

再来看一段代码:

	 let promise = new Promise((resolve, reject) => {
	      console.log(2);
	      resolve(2);
	  })
	  promise.then(res => res * 2).then(res => {
	      console.log('res:', res)
	  })
	  console.log(3);
  //结果输出:
  //   2
  //   3
  //   res:4

Promise中的then是微任务,不了解什么是微任务的同学可以先去了解下js运行机制
这里就用一种最简单的方式实现一下

	 then(onFulfilled, onRejected) {
	     onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val;
	     onRejected = typeof onRejected === 'function' ? onRejected : reson => { throw reson };
	     setTimeout(() => {
	       const thenPromise = new myPromise((resolve, reject) => {
	             if (this.promiseState === 'fulfilled') {
	                 let x = onFulfilled(this.promiseResult);
	                 argsType(x, resolve, reject);
	             }else if (this.promiseState === 'rejected') {
	                 let x = onRejected(this.promiseResult);
	                 argsType(x, resolve, reject);
	             }
	        })
	        return thenPromise;
	    })
	}
	// 判断x的类型
	function argsType(x, resolve, reject){
		 if(x instanceof myPromise){
		 	// x是promise
		 	then(resolve,reject);
		 }else{
		 	// x不是promise
		 	resolve(x);
		 }
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值