Promise

Promise 简单来说是异步编程的一种解决方案

Promise对象有以下两个特点:

(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。

(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。

(3)有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。

promise的写法
let mypromise=new Promise((resolve, reject)=>{
    setTimeout(()=>{
    resolve(100)  
    },1000);
});

mypromise.then((res)=>{
    console.log(res);
},()=>{
    console.log("no");
})
复制代码
用promise写Ajax
let pro=new Promise((resolve,reject)=>{
    let xhr=new XMLHttpRequest();
    xhr.open("get","js/1.js",true);
    xhr.onreadystatechange=()=>{
    if(xhr.readyState===4 && xhr.status===200){
        val=xhr.responseText;
        resolve(val);
    }
    if(xhr.status!==200){
        reject();
    }
    };
    xhr.send();
});

pro.then((res)=>{
    console.log(res);
    获取数据//数据绑定
},()=>{
    console.log("no不行");
})
复制代码
这样一来管理回调函数或者异步事件就很清楚了。可以后面继续追加.then();
then中两个方法,成功走第一个,失败走第二个,
比如实现某一种效果,就比如商品排序。

第一个then请求数据,绑定数据,渲染数据

第二个then从小到大排序

第三个then从大到小排序

let op=new Promise((resolve,reject)=>{
    //Ajax请求数据
})

op.then((res)=>{
    绑定数据//渲染数据
},()=>{
    
}).then(()=>{
    //商品排序
})
...以此内推
复制代码
一旦在第一个then中return了,那么返回结果就给了第二个then,以此内推。
这种设计模式,功能很强大,也方便了许多,从上面可以看出 .then()可以写很多个,那么promise的实现原理是什么呢?
接下来就小手撸代码,进入正题
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    class MyPromise{
        constructor(excutor){
        
            // 这里相当于MyPromise的函数体;
            // 在promise中分三个状态;pending  fulfilled rejected;
            // this --> promise的实例;给实例新增state属性,其属性值是"pending";
            
            this.state="pending";
            
            // 在实例上找了两块空间;一个是用来存储成功的回调,一个用来存储失败的回调;
            
            this.fulfilledEvent = [];
            this.rejectedEvent = [];
            this.value =undefined;
            
            let resolve = (result)=>{
                 // resolve : 这个函数是用来管控所有成功态的函数执行;
                // 一旦调用resolve,那么应该变成成功态;
                
                //if(this.state==="fulfilled"||this.state==="rejected")return;
                // 如果当前状态已经凝固,是成功或者失败中的一个,都不再执行;
                
                if(this.state!=="pending")return;
                this.state="fulfilled";
                this.value=result;
                clearTimeout(this.timer);
                 this.timer = setTimeout(()=>{
                    this.fulfilledEvent.forEach((item)=>{
                        if(typeof item==="function"){
                            item(this.value);
                        }
                    })
                 },0)
            };
            
            let reject=(result)=>{
                if(this.state!=="pending")return;
                this.state="rejected";
                clearTimeout(this.timer);
                this.value=result;
                this.timer = setTimeout(()=>{
                    this.rejectedEvent.forEach((item)=>{
                        if(typeof item==="function"){
                            item(this.value);
                        }
                    })
                },0)
            }
            try{
                excutor(resolve,reject)
            }catch(e){
                // 如果在函数中抛出异常,那么会调用下面then的reject的方法;
                reject(e);
            }

        }
        then(resolveFn,rejectedFn){
            if(resolveFn===undefined){
                //如果then没有传递函数,那么给当前默认赋值一个函数
                resolveFn=(result)=>{
                    return result
                }
            }
            if(rejectedFn===undefined){
                rejectedFn=()=>{
                    // 这个地方抛出异常,为了能够调用下个then的失败的方法;
                    throw new Error;
                }
            }
            
            
            // 为了确保下一次的then方法中的回调受上一次then方法中返回值的影响,
            //所以每次调用then,都返回一个不同的实例;
            
            return new MyPromise((resolve,reject)=>{
                // this --> then中this--> p1;
                this.fulfilledEvent.push(()=>{
                    // 需要验证当前resolveFn函数的返回值是否是一个Promise的实例;
                   try{
                       let x = resolveFn();
                       x instanceof MyPromise?x.then(resolve,reject):resolve();
                   }catch(e){
                       reject(e)
                   }
                });
                this.rejectedEvent.push(()=>{
                    try{
                        let x = rejectedFn();
                        x instanceof MyPromise?x.then(resolve,reject):resolve();
                    }catch(e){
                        reject(e)
                    }
                });
            });
        }
    }
    let p1 = new MyPromise(function (resolve,reject) {
        resolve(200)
    })
    console.log(1);
    let p2=p1.then(function (res) {
        return new MyPromise(function (resolve,reject) {
            reject();
        })
    },function () {
        console.log(101);
    });
    p2.then(function () {
        console.log(11);
    },function () {
        console.log(22);
    })

</script>
</body>
</html>
复制代码
注意:
  1. 当new 一个promise时,promise中的函数会立马执行
  2. 当promise的状态一旦固定,就不再改变
  3. 无法取消Promise,一旦新建它就会立即执行,无法中途取消
  4. 如果不设置回调函数,Promise内部抛出的错误,不会反应到外部
  5. 当处于pending状态时,无法得知目前进展到哪一个状态
then方法
  1. then : 为promise的实例增加状态发生改变时的回调函数
  2. then: 把第一个then中的回调的返回值会传递给第二个then回调的函数的形参
  3. then : 方法中内置会返回一个新的promise的实例;但不是之前的那个promise的实例了
  4. 前面一个回调函数中如果返回一个promise的对象,那么第二个回调函数会等待第一个返回的promise实例的状态发生变化才执行
promise的catch
  1. catch : 捕获当前异步的错误信息
  2. 如果在catch之前已经有then将错误信息进行处理,那么不再执行这个catch方法
  3. 如果第一个请求失败,那么不会再执行第二个请求
  4. catch : 只要之前的请求有一个失败,都会触发这个catch方法
promise的all
  1. all : 是将多个Promise的实例包装成一个promise的实例
  2. all方法是Promise这个类的私有方法
  3. all方法传递一个数组,数组中存放着Promise的实例;all方法返回一个promise的实例
  4. p1的成功或者失败的状态由数组中每一个promise的实例决定;当所有的实例的状态都是成功态,那么该p1的状态才是成功态,只要有一个失败,那么这个就会执行失败态
 let p1 = Promise.all([l1,l2,l3]).then(function () {},function () {})
复制代码
参考文档 es6.ruanyifeng.com/?search=pro…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值