promise实现及语法糖

2020-02-11  本文已影响0人  祝家庄打烊

基本语法(promise)

主要用于异步计算,可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果

 var a = new Promise(function(resolve,reject){  //执行器回调代码是同步任务
     setTimeout(function(){
         if(Date.now()%2==1){
             reject("错误信息:"+Date.now())
         }else{
             resolve("正确信息:"+Date.now())
         }
     },1000)
 })
 a.then(function(value){
     console.log("value1:",value);
     return "asdfds";
 }).then(function(value){
     console.log("value2:",value)
 }).catch(function(reason){
     console.log(reason);
 });

语法糖,简易写法,方便、实用(promise)

一、resolve和reject

var c = Promise.resolve(3);
var d = Promise.resolve(4);
var f = Promise.resolve(Promise.reject(5));
c.then(function(value){console.log(value)});
d.then(function(value){console.log(value)});
f.catch(function(value){console.log(value)});

二、all用法,接收promise数组,返回结果对象,数组中只要有一个是reject,都会走catch函数
Promise.all([b,c,d]).then(function(values){console.log("all",values)});
三、race用法,接收promise数组,返回较快算出的那一个promise
Promise.race([b,c,d]).then(function(value){console.log("race",value)});

async...await用法

一、async定义的函数,返回值是一个promise对象,可通过then接收

async function g(){
     return 1;
}
console.log(g())

二、await必须和async连用,返回值是promise对象resolve的结果

var e = new Promise(function(resolve){
    resolve(666)
})
async function h(){
    var a = await e;
    console.log(a);
};
h()

实现promise

一、使用立即执行函数包裹promise构造函数,对变量私有化

(function(window){})()

二、定义构造函数,内部定义数据(data),状态(status),接收成功、失败的回调函数。函数接收执行器函数excute,执行器函数接收两个函数,成功resolve和失败rejected。执行resolve和reject函数,改变status值和对data进行赋值。

function resolve(value){
      _that.status = "resolved";
      _that.data = value;
      if(_that.callback.length>0){
            setTimeout(function(){
                _that.callback.forEach(function(item){
                    item.onResolve(_that.data);
                })
            },0)
      }
}

三、定义then方法
方法接收onResolve和onReject回调函数,状态为pending,说明promise对象是异步操作,利用发布订阅者模式对回调函数进行存储。状态为resolve和reject,说明promise对象是同步操作,可立即执行回调函数。then方法的链式调用者需要返回新的promise对象,onResolve函数返回的结果值,作为新的promise回调函数resolve的值。

Promise.prototype.then = function(onResolve,onReject){
    var _that = this;
    return new Promise(function(resolve,reject){
        function handle(callback){
            try{
                var data = callback(_that.data);
                //返回是否为promise对象
                if(data instanceof Promise){
                    data.then(function(value){
                       resolve(value)
                    },function(reason){
                        reject(reason)
                    })
                }else{
                    resolve(data);
                }
           }
           catch(error){
                reject(error)
            }
        }
        if(_that.status == "pending"){
            _that.callback.push({
               "onResolve":function(value){
                    handle(onResolve)
                },
               "onReject":function(reason){
                    handle(onReject);
                }
            })
        }
        if(_that.status == "resolved"){
            setTimeout(function(){
                handle(onResolve)
            })
        }
        if(_that.status == "rejected"){
            setTimeout(function(){
                handle(onReject);
            })
        }
    })
}

四、定义函数属性resolve方法
利用之前写好的promise构造函数进行二次封装,返回new promise对象,判断resolve方法参数是否promise对象,否则直接调用resolve,是则调用then方法。

Promise.resolve = function(value){
   return new Promise(function(resolve,reject){
        if(value instanceof Promise){
            value.then(resolve,reject)
        }else{
            resolve(value)
        }
    })
 }

五、定义函数属性all方法
接收参数为promise对象的数组,返回promise对象,对接收的参数进行遍历,调用遍历出的每个promise对象的then方法,值都对应起来存储到外部定义的数组上,直到都处理完成,都成功才返回结果,有一个失败调用失败(reject)回调函数。

Promise.all = function(res){
    var values = [];
    var idx = 0;
    return new Promise(function(resolve,reject){
        res.forEach(function(item,index){
            item.then(function(value){
                idx++;
                values[index] = value;
                if(idx==res.length){
                    resolve(values)
                }  
            },function(reason){
                reject(reason)
            })
        })
    })
}

项目案例

上一篇 下一篇

猜你喜欢

热点阅读