function isFunction(fn){
return Object.prototype.toString.call(fn) === '[object Function]';
} let ST = {
pending: 0,
resolved: 1,
rejected: 2
} function Promise(fn){
let self = this;
self.status = ST.pending;
self.value = '';
self.reason = '';
self.resolveFns = [];
self.rejectFns = []; //setTimeout延迟执行,将reslove执行放在下个循环,保证后续then方法先于它执行,不会出现前面已经resolve了,后面的then还没push进resolveFns数组
function resolve(val){
setTimeout(() => {
if(self.status == ST.pending){
self.status = ST.resolved;
self.value = val;
//用数组保存回调,是为了处理一个promise挂载多个then的情况
//注意不是链式,这种场景很少出现
/*
形如:
promise.then(resolve1,reject1)
promise.then(resolve2,reject2)
promise.then(resolve3,reject3)
*/
//在链式调用中,该数组通常只会有一个项,就是当前promise的下一个then里面的resolve函数
//且每次执行,通常都是一个新Promise的resolve数组
self.resolveFns.forEach(fn => fn());
}
})
} function reject(val){
setTimeout(() => {
if(self.status == ST.pending){
self.status = ST.rejected;
self.reason = val;
self.rejectFns.forEach(fn => fn());
}
})
} //执行出问题,直接reject,Promise的错误默认不会抛出到全局
try{
fn(resolve,reject);
}
catch(err){
reject(err);
}
} Promise.prototype.then = function(onResolve,onReject){
let self = this; //then每次执行都返回一个新的Promise,then方法要处理前一个promise的三种状态
return new Promise(function(resolve,reject){
function handle(value,thenFn){
let res = isFunction(thenFn) && thenFn(value) || value;
if(res instanceof Promise){
res.then(resolve,reject);
}
else{
resolve(res);
}
} //处理三种状态
//fn函数体里,如果有错误; 会执行try catch里的 reject方法,执行then this.state就是rejected
//如果没错误且没异步,resolve this.state就是resolved
//如果没错误且有异步,this.state就是pending
if(self.status == ST.pending){
self.resolveFns.push(resloveHandle);
self.rejectFns.push(rejectHandle);
}
else if(self.status == ST.resolved){
self.handle(self.value,onResolve);
}
else if(this.status == ST.rejected){
self.handle(self.reason,onReject);
}
})
} Promise.prototype.catch = function(onReject){
return this.then(undefined, onReject);
} //finally不是promise的末尾,后面还可以有then,所以value和reason必须可以向下传递
Promise.prototype.finally = function(fn){
let P = this.constructor;
return this.then(
value => P.resolve(fn()).then(() => value),
reason => P.resolve(fn()).then(() => throw reason);
)
} //done作为promise的末尾,用于收集所有可能的报错,catch方法捕捉所有错误,并抛出
Promise.prototype.done = function(resolve,reject){
return this.then(resolve, reject).catch(function(reason){
setTimeout(function(){
throw reason;
});
})
} Promise.resolve = function(val){
return new Promise((resolve) => {
resolve(val);
})
} Promise.reject = function(val){
return new Promise((resolve,reject) => {
reject(val);
})
} Promise.race = function(promises){
let len = promises.length; return new Promise(function(resolve,reject){
while(len--){
promises[len].then(resolve,reject);
}
})
} Promise.all = function(promises){
let len = promises.length,
results = []; return new Promise(function(resolve,reject){
//用一个数组收集单个promise执行后的结果,收集满数组所有结果,便是所有执行成功
function reslove(index){
return function(value){
results[index] = value;
if(results.length == len){
reslove(results);
}
}
} while(len--){
promises[len].then(resolve(len),reject);
}
})
}

最新文章

  1. Linux异常表
  2. centos7 + VMware Workstation Pro
  3. selenium处理滚动条
  4. C#学习之初步理解委托、事件、匿名方法和Lambda
  5. iis7.5中使用fastcgi方式配置php5.6.5
  6. WM_ACTIVATE
  7. thinking in java知识小记(一)
  8. 【九】注入框架RoboGuice使用:(Your First Injected Service and BroadcastReceiver)
  9. 【Unity Shaders】Mobile Shader Adjustment —— 为手机定制Shader
  10. 软工+C(2017第7期) 野生程序员
  11. 201521123122 《java程序设计》第十三周学习总结
  12. os系统
  13. Java编码与乱码问题
  14. sofa-rpc 服务端源码流程走读
  15. CF 329A(Purification-贪心-非DLX)
  16. 洛谷P3157 动态逆序对 [CQOI2011] cdq分治
  17. python的变量的命名规则以及定义
  18. Java中如何判断一个字符串是否为数字
  19. oracle 插入单引号
  20. Sea Battle<海战>(思路题)

热门文章

  1. Httpd服务入门知识-Httpd服务常见配置案例之基于客户端来源地址实现访问控制
  2. SpringMVC使用@Valid注解进行数据验证
  3. httprunner学习18-多进程运行模式
  4. Spring Boot Configuration Annotation Proessor not found in classpath解决办法
  5. JVM 性能调优工具
  6. 洛谷P2882 [USACO07MAR]面对正确的方式Face The Right Way(贪心)
  7. CF632E Thief in a Shop 和 CF958F3 Lightsabers (hard)
  8. python Tkinter的Text组件中创建x轴和y轴滚动条,并且text文本框自动更新(三)
  9. sql 查询哪些字段重复及(in和exict的区别)
  10. 2019阿里JVM组实习面经