ES6-22【手写实现之 Promise】

一.promise总结

  1. promise是一个容器
  2. 保存着某个未来才会结束的事件的结果
  3. 从语法上说,promise是一个对象
  4. 可能是成功的结果,也可能是失败的结果

二.基础Promise实现

function Promise(fn) {
        var callback = '';
        this.then = function (cb) {
            console.log(cb);

            callback = cb;
        }
        function resolve(value) {
            setTimeout(function () {
                callback(value)
            }, 100)
        }
        fn(resolve)
    }
    function doSomething() {
        return new Promise((resolve) => {
            var value = 66;
            resolve(66);
        })
    }
    var promise1 = doSomething();
    var promise2 = promise1.then((data) => {
        console.log('Got a value' + data);
    });

此处通过settimeout来控制了callback最后执行,让调用then能成功赋值callback

去除timeout

function Promise(fn){
    let state= 'peanding',
        value = '';
    this.then=(onResolved)=>{
        handler(onResolved);
    }
    function resolve(resolve){
        value = resolve;
        state = 'resolved'
    }
    function handler(onResolved){
        onResolved(value)
    }
    fn(resolve);
}
function doSomeThing(){
    return new Promise(function(resolve){
        var value = 66;
        resolve(66);
    })
}
var promise1 = doSomeThing();
var promise2 = promise1.then(function(data){
    console.log('Got a value'+data);
    
})
Got a value66

不在resolve中处理then中得函数,resolve只负责将入参缓存在本地 在then中响应函数

三.链式调用

function Promise(fn){
    let state= 'peanding',
        value = '';
    this.then=(onResolved)=>{
        return new Promise((resolve)=>{
            handler({
                resolve:resolve,
                onResolved:onResolved
            })
        })
    }
    function resolve(resolve){
        value = resolve;
        state = 'resolved'
    }
    function handler(onResolved){
        
        if(!onResolved.onResolved){
            onResolved.resolve(value)
            return
        }
       var retrunValue = onResolved.onResolved(value);
       onResolved.resolve(retrunValue)
    }
    fn(resolve);
}
function doSomeThing(){
    return new Promise(function(resolve){
        var value = 66;
        resolve(66);
    })
}
var promise1 = doSomeThing();
var promise2 = promise1.then(function(data){
    console.log('Got a value'+data);
    return 88;
}).then((data)=>{
    console.log('Got a second'+data);
})

使用递归实例化的方式将resolve传入这样就可以分为两次缓存value值了,而第二次的value值为第一次函数执行出来的值,如果t'hen中什么都不填就会自动忽略

四.return promise

不科学得写法

function Promise(fn){
    let state= 'peanding',
        value = '';
    this.then=(onResolved)=>{
        return new Promise((resolve)=>{
            handler({
                resolve:resolve,
                onResolved:onResolved
            })
        })
    }
    function resolve(resolve){
        value = resolve;
        state = 'resolved'
    }
    function handler(onResolved){
        
        if(!onResolved.onResolved){
            onResolved.resolve(value)
            return
        }
       var retrunValue = onResolved.onResolved(value);
       onResolved.resolve(retrunValue)
    }
    fn(resolve);
}
function doSomeThing(){
    return new Promise(function(resolve){
        var value = 66;
        resolve(66);
    })
}
function doSomeThingElse(value){
    return new Promise(function(resolve){
        resolve(`did something else with`+value);
    })
}
var promise1 = doSomeThing();
var promise2 = promise1.then(function(data){
    console.log('Got a value'+data);
    return doSomeThingElse(data);
}).then(function(anotherPromise){
    anotherPromise.then(function(finalResult){
        console.log(`Got a second value:`+finalResult);
        
    })
})
Got a value66
Got a second value:did something else with66

通过返回的promiseFunction再次调用then解析,这样是不科学的

科学写法

function Promise(fn){
    let state= 'peanding',
        value = '';
    this.then=(onResolved)=>{
        return new Promise((resolve)=>{
            handler({
                resolve:resolve,
                onResolved:onResolved
            })
        })
    }
    function resolve(newValue){
        if(newValue && typeof newValue.then === 'function'){
            //上面这里也可以直接判断 newVlue.then是否存在即可区别
            newValue.then(resolve)
            return;
        }
        value = newValue;
        state = 'resolved'
    }
    function handler(onResolved){
        
        if(!onResolved.onResolved){
            onResolved.resolve(value)
            return
        }
       var retrunValue = onResolved.onResolved(value);
       onResolved.resolve(retrunValue)
    }
    fn(resolve);
}
function doSomeThing(){
    return new Promise(function(resolve){
        var value = 66;
        resolve(66);
    })
}
function doSomeThingElse(value){
    return new Promise(function(resolve){
        resolve(`did something else with`+value);
    })
}
var promise1 = doSomeThing();
var promise2 = promise1.then(function(data){
    console.log('Got a value'+data);
    return doSomeThingElse(data);
}).then(function(anotherPromise){
    
        console.log(`Got a second value:`+anotherPromise);
        
    
})
Got a value66
Got a second value:did something else with66

在resolve中判断传进来的参数是否为promise对象,如果是的话则调用then重新再处理一遍即可

五.处理失败时写法

function Promise(fn){
    let state= 'peanding',
        value = '';
    this.then=(onResolved,onReject)=>{
        return new Promise((resolve,reject)=>{
            handler({
                resolve:resolve,
                reject: reject,
                onResolved:onResolved,
                onReject:onReject
            })
        })
    }
    function resolve(newValue){
        if(newValue &&  newValue.then ){
            newValue.then(resolve)
            return;
        }
        value = newValue;
        state = 'resolved'
    }
    function reject(newValue){
        if(newValue &&  newValue.then ){
            newValue.then(reject)
            return;
        }
        value = newValue;
        state = 'rejected'
    }
    function handler(onResolved){
        var callBackHand;
        if(state === 'resolved'){
            callBackHand = onResolved.onResolved
        }else{
            
            callBackHand = onResolved.onReject
        }
        if(!callBackHand){
            if(state === 'resolved'){
                onResolved.resolve(value)
                return
            }else{
                onResolved.reject(value)
            }  
        }
       var retrunValue =callBackHand(value);
       if(state === 'resolved'){
            onResolved.resolve(retrunValue)
            return
        }else{
            onResolved.reject(retrunValue)
        } 
    }
    fn(resolve,reject);
}
function doSomeThing(){
    return new Promise(function(resolve,reject){
        reject(66);
    })
}

var promise1 = doSomeThing();
var promise2 = promise1.then(function(data){
    console.log('Success'+data);
   
},function(data){
    console.log('Fail'+data);
    
})

增加了reject方法,其它方法中均加入reject参数,以及状态的判断即可

六.边角处理

错误捕获/异步实现

function Promise(fn){
    let state= 'peanding',
        value = '';
    this.then=(onResolved,onReject)=>{
        return new Promise((resolve,reject)=>{
            handler({
                resolve:resolve,
                reject: reject,
                onResolved:onResolved,
                onReject:onReject
            })
        })
    }
    function resolve(newValue){
        try{
        if(newValue &&  newValue.then ){
            newValue.then(resolve)
            return;
        }
        value = newValue;
        state = 'resolved'
        }catch(err){
            reject(err)
        }
    }
    function reject(newValue){
        if(newValue &&  newValue.then ){
            newValue.then(reject)
            return;
        }
        value = newValue;
        state = 'rejected'
    }
    function handler(onResolved){
        setTimeout(function(){
            var callBackHand;
            if(state === 'resolved'){
                callBackHand = onResolved.onResolved
            }else{
                
                callBackHand = onResolved.onReject
            }
            if(!callBackHand){
                if(state === 'resolved'){
                    onResolved.resolve(value)
                    return
                }else{
                    onResolved.reject(value)
                }  
            }
            try{
             var retrunValue =callBackHand(value);
            }catch(err){
                reject(err)
            }
           if(state === 'resolved'){
                onResolved.resolve(retrunValue)
                return
            }else{
                onResolved.reject(retrunValue)
            } 
        })
       
       
    }
    fn(resolve,reject);
}
function doSomeThing(){
    return new Promise(function(resolve,reject){
        reject(66);
    })
}

var promise1 = doSomeThing();
var promise2 = promise1.then(function(data){
    console.log('Success'+data);
   
},function(data){
    console.log('Fail'+data);
    
})
console.log(2);

2
Fail66

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值