微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐