仿promise
以下个人观点,不对地方请指正
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");
})()