程序员

仿promise

2018-03-10  本文已影响0人  小银

以下个人观点,不对地方请指正
promise可以说是现在前端代码的标配(再也不想循环嵌套了),
先说下特征吧
1.promise有状态(进行中,已完成,已失败)和其对应的处理函数。
如果是正在进行中,则不执行对应的处理函数,
如果是已完成执行对应的then函数的第一个回调。
如果是已失败只能被捕获可以是catch方法也可以是then的第二个回调(失败的promise只能
被捕获一次,接下来的链式catch是不能捕获的)

var p=new Promise((r1,r2)=>{r2(1)});
p.catch(v=>console.log("c1")).catch(v=>console.log("c2")).then(v=>console.log("t1"));
//只会输出c1和t1

2.已完成状态(resolve(1))和已完成的处理程序没有先后关系

var p=new Promise((r1,r2)=>{setTimeout(()=>{r1(1)
},3000)});setTimeout(()=>{p.then(v=>{console.log(v)})},1000)
//延迟处理也能执行,只要是完成状态并有对应的处理程序

3.未完成(reject(1))和未完成的处理程序必须绑定否则

var p=new Promise((r1,r2)=>{r1(1)});
//如果不写对应的p.catch...或者p.then(null,v=>{})就会报错

4.then或者catch返回的是一个新的promise 并且状态是已完成,值根据是否return (如果return的是一个promise,则根据这个promise的状态来决定),在对应的处理函数力return一个值不会改变原来的值

var p=new  Promise((r1,r2)=>{r1(1)});
p1=p.then(v=>{return v+1});
p2=p.then(v=>console.log(v));
p1.then(v=>console.log(v));
p2.then(v=>console.log(v));
//输出的是1    2   undefine

var p2=new Promise((r1,r2)=>{r1("p2")})
p3=p2.then(v=>{return p2});
p3.then(v=>console.log(v));
//输出p2  
var p2=new Promise((r1,r2)=>{})
p3=p2.then(v=>{return p2});
p3.then(v=>console.log(v));
//不输出,p2和p3都是pending 

试下实现了下它的一些基本功能(任务队列,生命周期,resolve的状态,reject的状态,then方法,catch方法,串联 )
待实现功能:all方法,race方法 promise全局处理
var uid=0
uid:标示符
status:状态(标示生命周期的3个状态)
que:任务队列
newval:当前值,
originval:原始值,
nextPromise:连接的promise
isNeedCatch:是否要捕获的标示
resolve方法:改变状态已完成,并异步执行(promise是在事件循环的结尾)完成队列的数据
reject方法:改变状态为未完成,并异步执行(promise是在事件循环的结尾)未完成队列的数据
then方法:把resolve和reject添加到对应的队列里去
catch方法:把reject添加到对应的队列里去
run方法:根据状态,任务队列,下一个promise去执行对应的回调函数。

后续再补填全局方法
demo github地址

在这里补充个promise+迭代器实现async+await
任务执行代码


var fs={
    readFile:function(fliename,cb){
    var name=fliename;
    setTimeout(()=>{
        cb(null,"fliename="+name,+"内容是xxxxx")
    },3000)
}
} 
//创建任务
function run(taskDef){
//创建迭代器
let task=taskDef();//taskDef是个Generator  Generator  方法执行后返回的是一个迭代器
let result= task.next();
//递归遍历
(function setp(){//每个setp对应一个yeil
      if(!result.done){
      let promise=Promise.resolve(result.value);
    promise.then(function(value){
      result=task.next(value);
      setp();
}).catch(function(error){
      result=task.throw(error);
      setp();
})
    }
}())
}
//定义一个可执行函数 函数的放回值必须是promise
function readFile(fliename){
    return new Promise(function(resolve,reject){
    fs.readFile(fliename,function(err,contents){
        if(err){
            reject(err);
        }else{
            resolve(contents);
        }
    })
    })
}
run(function* (){
    let contens=yield readFile("config.json");
    doSomethingWith(contens);
    let contens2=yield readFile("config.json2");
    doSomethingWith(contens2);
    console.log("Done");
})
function doSomethingWith(contents){
console.log(contents)

}

//用await实现
(async function(){
    let contens=await readFile("config.json");
    doSomethingWith(contens);
    let contens2=await readFile("config.json2");
    doSomethingWith(contens2);
    console.log("Done");
})()
上一篇 下一篇

猜你喜欢

热点阅读