手写Promise

1.promise的实例方法实现

1.1 整体结构搭建

 ^引入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>Document</title>
    <!-- <script src="./promise.js"></script> -->
</head>
<body>
    <script>
        let p = new Promise((resolve,reject)=>{
            resolve('ok');
        })
        p.then(value=>{
            console.log(value);
        },reason=>{
            console.warn(reason);
        })
    </script>
</body>
</html>

^promise.js

//声明构造函数
function Promise(executor){

}

// 添加then方法
Promise.prototype.then = function(onResolved,onrejected){

}

 1.2 resolve和reject函数的构建和实现

1.resolve是直接调用的,resolve中的this指向window。所以应该用const self = this来保存实例对象。

2.设置promise的基础状态:PromiseState = 'pending'和PromiseResult = null;

^promise.js

// 声明构造函数
function Promise(executor){
    // 添加属性
    this.PromiseState = 'pending';
    this.PromiseResult = null;
    // 保存实例对象的this的值
    const self = this;
    // resolve函数
    function resolve(data){
        // 1.修改对象的状态(promiseState)
        self.PromiseState = 'fulfilled'; // resolved
        // 2.设置对象的结果值(promiseResult)
        self.PromiseResult = data;
    }
    // reject函数
    function reject(data){
        // 1.修改对象的状态(promiseState)
        self.PromiseState = 'rejected';
        // 2.设置对象的结果值(promiseResult)
        self.PromiseResult = data;
    }
    // 执行器函数在内部是同步调用的
    executor(resolve,reject);
}

// 添加then方法
Promise.prototype.then = function(onResolved,onrejected){

}

1.3 throw抛出异常改变状态 

 1.把上面“同步调用执行器函数”加上try...catch

 2.抛出异常状态时,修改promise状态为失败,直接调用reject()即可

// 执行器函数在内部是同步调用的
    try{
        executor(resolve,reject);
    }catch(e){
        // 修改promise对象的状态为失败
        reject(e);
    }

 1.4 Promise对象的状态只能修改一次

 1.promise对象的状态只能修改一次,即从pending->fulfilled或者pending->rejected

 2.在改变状态之前,先判断一下promise的状态是否被改变过

^html调用

<script>
        let p = new Promise((resolve,reject)=>{
            resolve('ok');
            reject('no');
        })

        console.log(p)
    </script>

 ^promise.js修改 (添加判断状态)

// resolve函数
    function resolve(data){
        // !判断状态
        if(self.PromiseState !== 'pending') return;
        ...
    }
    // reject函数
    function reject(data){
        // !判断状态
        if(self.PromiseState !== 'pending') return;
        ...
    }

1.5 then方法执行回调

1.调用回调函数,如果成功,调用onResolved(),如果失败则调用onRejected()

2.成功或失败看的是PromiseState属性

3.then方法是p调用的,所以在then方法中直接使用this.PromiseState 可以获取到p身上的PromiseState

^html引入

<script>
        let p = new Promise((resolve,reject)=>{
            // resolve('ok');
            // reject('error');
            throw "ohh";
        })

        p.then(value=>{
            console.log(value);
        },reason=>{
            console.warn(reason);
        })
    </script>

^promise.js

// 添加then方法
Promise.prototype.then = function(onResolved,onrejected){
    // 调用回调函数
    if(this.PromiseState === 'fulfilled'){
        onResolved(this.PromiseResult);
    }
    if(this.PromiseState === 'rejected'){
        onrejected(this.PromiseResult);
    }
}

1.6 异步任务回调的执行

1.当加了异步任务时,执行器内部代码还未返回,再往下执行then函数时,promise的状态是penging,既不成功也不失败,无法触发resolve和reject方法

2.当执行到then时,最后要判断状态是否为pending,如果是,则要保存回调函数到实例对象

3.当代码运行到异步队列的resolve或reject时,调用回调函数,实现异步then

^html引入

<script>
        let p = new Promise((resolve,reject)=>{
            setTimeout(()=>{
            //    resolve('ok'); 
            reject('error')
            },1000)
        })

        p.then(value=>{
            console.log(value);
        },reason=>{
            console.warn(reason);
        })
        console.log(p)
    </script>

 ^promise.js

// 声明构造函数
function Promise(executor){
    ...
    // 声明属性
    this.callback = {};
    ...
    // resolve函数
    function resolve(data){
        ...
        // 调用成功的回调函数
        if(self.callback.onResolved){
            self.callback.onResolved(data);
        }
    }
    // reject函数
    function reject(data){
        ...
        // 调用失败的回调函数
        if(self.callback.onRejected){
            self.callback.onRejected(data);
        }
    }
    ...
}

// 添加then方法
Promise.prototy
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值