Promise

Promise

什么是Promise?
  • Promise 在英文中的意思是承诺。在程序中表示,承诺在一段时间后给出结果。
  • Promise 是解决异步编程的一种方案。
  • Promise 由社区最早提出和实现,在ES6中归入语言标准,所以 Promise 是原生自带的
我们为什么要需要 promise
  • 回调地狱-> 在需要多个操作的时候,会导致我们的函数内部嵌套多个函数,导致代码不够清晰和维护
  • 并发结果-> 如果几个异步操作之间并没有前后顺序之分,但需要同一时刻完成执行结果
promise 的三种状态
  • Pending 等待状态,也可以认为一个promise实例的默认状态 Pending可以转化为 Fulfilled 或 Rejected
  • Fulfilled 成功状态
  • Rejected 失败状态
promise 是微任务
promise 原型方法

Promise.prototype.then

  • 每一个 promise 实例都拥有一个then方法
  • 是异步方法,有2个参数,分别是 resolve,reject
  • 在then中 resolve 、reject 只会执行其中一个
  • then 方法返回的结果会取决于上一个then的结果
  • then().then() 对于这种then 不写任何参数的,会直接把值传递到下面的。这种也叫做值穿透
  • then 不写成功态时,把第一个参数改为null
let p =  new Promise(function (resolve,reject) {
  // 如果在这里调用了resolve 就会变成成功态
  // 同时调用resolve 和reject 只会执行一个
  reject();
  resolve();
});
p.then().then().then().then(function () { // 成功
  console.log('成功')
},function () { // 失败
  console.log('失败')
});
console.log('xxxx');

Promise.prototype.catch

  • 捕获异常,上一个then中没有写err参数,并有err时捕获异常
    //catch 用于上一个then 没有写接受err 时捕获err
p.then(function(data){
    console.log(data);
}).catch(function(err){ 
    console.log(err);
}
Promise.prototype.finally
不管成功还是失败都会执行

Promise.prototype.finally

  • 最终的不管成功还是失败都会执行
let Promise = require('./promise3')
let p = Promise.reject('xxx');
p.finally(function () {
  console.log('xxxx');
}).then(function (data) {
  console.log('success', data);
}, function (err) {
  console.log('error', err);
});
promise 类方法

Promise.resolve

  • 返回一个成功态的promise实例,并把传入的值返回

Promise.reject

  • 返回一个失败态的promise实例,并把传入的值返回

Promise.all 并发方法

  • 参数是数组,数组内都是promise的实例
  • 返回一个primes实例
  • 参数的promise都是成功状态,则返回的这个promise就是resolve。如果有一个- 是失败状态,则返回的promise就是reject。
Promise.all([1,3]).then(function (data) {
  console.log(data);
},function (err) {
  console.log(err)
})

Promise.race

  • 参数是数组,数组内都是promise的实例
  • 返回一个promise实例
  • 返回的promise实例的结果会取 参数中最快的一个作为返回值
Promise.race([1,3]).then(function (data) {
  console.log(data);
},function (err) {
  console.log(err)
})
Promise 的链式调用
  • then 可以使用链式调用主要是,每次调用then之后都会返回一个新的promise,返回的这个promise的成功或失败用于执行下一个then,如果返回的是一个普通值,则直接是下一个then的成功状态的。

promise 实例内,是同步代码

let p = new Promise(function(resolve,rejct){
  console.log(111); //这里是同步代码
  resolve(333)
})
p.then(function(va){
  console.log(va);
})
console.log(222);

重点来啦

模仿promise

class Promose{
    constructor(execuor){
        this.value = "";
        this.reason = "";
        this.state = "pending";
        this.onResolveCallback = [];
        this.onRejectCallback = [];

        let resonlve = value=>{
            if(this.state === "pending"){
                this.value = value;
                this.state === "resolved";
            }
        }
        let reject = reason =>{
            if(this.state === "pending"){
                this.reason = reason;
                this.state = "rejected";
            }
        }
        try{
            execuor(resonlve,reject);
        }catch(e){
            reject(e)
        }
    }
    // promsie 核心事件
    resolvePromise(promise2,x,resolve,reject){
        if(x === promise2){//表示是同一个东西,就循环引用
            reject(new TypeError("循环引用啦"))
        }
        let clled;
        if(x !== null && (typeof x === "function" || typeof x === "object")){//表示x可能是一个promise
            try{//x可能是一个异常
                let then = x.then;
                if(typeof then === "function"){//判断x.then是不是一个函数,如果是一个函数则认为就是一个promise
                    then.call(x,y=>{
                        if(!clled){
                            clled = true;
                        }else{
                            return
                        }
                        // reject(y);
                        resolvePromise(promise2,y,resolve,reject);// 有可能 y也是一个promise,所以用递归一直递归到是一个普通值
                    },r=>{
                        if(!clled){
                            clled = true;
                        }else{
                            return
                        }
                        reject(r);
                    })
                }else{//如果x上面有then属性,但可能是这样的{then:111}
                    resolve(x)
                }
            }catch(e){
                if(!clled){
                    clled = true;
                }else{
                    return
                }
                reject(e);
            }
        }else{//x是一个普通值
            resolve(x);
        }
    }
    then(onFulfilled,onReject){
        let promise2 = new Promise((resolve,reject)=>{
            if(this.state === "resolved"){ 
                setTimeout(()=>{ // 加定时器是因为要异步拿到promise2,同步那不到
                    try{
                        let x = onFulfilled(this.value);
                        resolvePromise(promise2,x,resolve,reject);
                    }catch(e){
                        reject(e);
                    }
                },0)
            }
            if(this.state === "rejected"){
                setTimeout(() => {
                    try{
                        let x = onReject(this.reason);
                        resolvePromise(promise2,x,resolve,reject);
                    }catch(e){
                        reject(e);
                    }
                }, 0);
            }
            if(this.state === "pending"){
                this.onResolveCallback.push(()=>{
                    setTimeout(() => {
                        try{
                            let x = onFulfilled();
                            resolvePromise(promise2,x,resolve,reject);
                        }catch(e){
                            reject(e);
                        }
                    }, 0);
                });
                this.onRejectCallback.push(()=>{
                    setTimeout(() => {
                        try{
                            let x = onReject();
                            resolvePromise(promise2,x,resolve,reject);
                        }catch(e){
                            reject(e);
                        }
                    }, 0);
                });
            }
        })
        return promise2
    }

    catch(errFn){
        return this.then(null,errFn)
    }
    finally(callback){
        return this.then(value=>{
            return Promise.resolve(callback()).then(()=>{
                return value;
            })
        },reason=>{
            return Promise.resolve(callback()).then(()=>{
                throw reason;
            })
        })
    }
    static reject(reason){
        return new Promise((resolve,reject)=>{
            reject(reason);
        })
    }
    static resolve(value){
        return new Promise((resolve,reject)=>{
            resolve(value);
        })
    }

    static all(promise){
        return new Promise((resolve,reject)=>{
            let arr = [];
            let i = 0;
            let processData = (inx,data)=>{
                arr[inx] = data;
                if(++i === promise.length){
                    resolve(arr)
                }
            }
            for(let i = 0;i<promise.length;i++){
                let promise = promose[i];
                if(typeof promise.then === "function"){
                    promise.then(value=>{
                        processData(i,value);
                    })
                }else{
                    processData(i,promise)
                }
            }
        })
    }
    static race(promise){
        return new Promise((resolve,reject)=>{
            for(let i=0;i<promise.length;i++){
                let promise = promise[i];
                if(typeof promise.then === "function"){
                    promise.then(resolve,reject);
                }else{
                    resolve(promise);
                }
            }
        })
    }
    
    //这个方法是一个检测是否promise,现在基本没人用了
    static deferred(){ 
        let dfd = {};
        dfd.Promise = new Promise((resolve,reject)=>{
            dfd.resolve = resolve;
            dfd.reject = reject;
        })
        return dfd;
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值