Promise原理剖析
var promise=new Promise(function(resolved,rejected){
console.log(1);
resolved('123');
})
promise.then(function(data){
console.log('success'+data)
},function(err){
console.log('fail'+err)
})
function Promise(executor){
let self=this;
self.status='pending';
self.value=undefined;
self.reason=undefined;
function resolve(value){
if(self.status==='pending'){
self.value=value;
self.status='resolved';
}
}
function reject(reason){
if(self.status==='pending'){
self.reason=reason;
self.status='rejected';
}
}
try{
executor(resolve,reject) //第一步:先执行executor,根据里面resolve和reject的调用,执行上面的resolve和reject方法
}catch(e){
reject(e);
}
}
Promise.prototype.then=function(onFulfilled,onRejected){
let self=this;//第二步:then被调用的时候根据已经记录的promise状态,执行成功方法或失败方法
if(self.status==='resolved'){
onFulfilled(self.value);
}
if(self.status==='rejected'){
onRejected(self.reason);
}
}
module.exports = Promise
var promise=new Promise(function(resolve,reject){
console.log('hello')
setTimeout(function(){
resolve('ok')
},1000);
})
promise.then(function(data){
console.log('success'+data)
},function(err){
console.log('fail'+err)
})
function Promise(executor){
let self=this;
self.status='pending';
self.value=undefined;
self.reason=undefined;
self.onResolvedCallbacks=[];
self.onRejectedCallbacks=[];
function resolve(value){
if(self.status==='pending'){
self.value=value;
self.status='resolved';
self.onResolvedCallbacks.forEach(item=>item());//最终执行resolve方法时,修改状态,将成功数组中的方法取出,一一执行。
}
}
function reject(reason){
if(self.status==='pending'){
self.reason=reason;
self.status='rejected';
self.onRejectedCallbacks.forEach(item=>item());//最终执行reject方法时,修改状态,将失败数组中的方法取出,一一执行。
}
}
try{
executor(resolve,reject)
}catch(e){
reject(e);
}
}
Promise.prototype.then=function(onFulfilled,onRejected){
let self=this;
if(self.status==='resolved'){
onFulfilled(self.value);
}
if(self.status==='rejected'){
onRejected(self.reason);
}
if(self.status==='pending'){ //执行then的时候是等待态,就将成功方法存入onResolvedCallbacks数组,将失败方法存入onRejectedCallbacks数组
self.onResolvedCallbacks.push(function(){
onFulfilled(self.value);
});
self.onRejectedCallbacks.push(function(){
onRejected(self.reason);
});
}
}
module.exports = Promise
let p=new Promise((resolve,reject)=>{
console.log(1);
setTimeout(function(){
resolve('123');
},1000);
})
let p2=p.then((data)=>{
console.log(data);
return new Promise((resolve,reject)=>{
setTimeout(function(){
resolve('456');
},1000);
});
},err=>{
console.log(err);
throw Error('失败');
}).then((data)=>{
console.log('aaa'+data);
},(err)=>{
console.log(err);
})
function Promise(executor){
let self=this;
self.status='pending';
self.value=undefined;
self.reason=undefined;
self.onResolvedCallbacks = []; // 存放then成功的回调
self.onRejectedCallbacks = []; // 存放then失败的回调
function resolve(value){
if(self.status==='pending'){ //这里面的self不能用this替代,因为是回调执行的时候不是在类里面所以这里的this不是类函数
self.status='resolve';
self.value=value;
self.onResolvedCallbacks.forEach(item=>{item()})
}
}
function reject(reason){
if(self.status==='pending'){
self.status='reject';
self.reason=reason;
self.onRejectedCallbacks.forEach(item=>{item()})
}
}
try{
executor(resolve,reject);
}catch(e){
reject(e);
}
}
function resolvePromise(promise2,x,resolve,reject){
if(promise2===x){//自己等于自己,报类型错误
return reject(new TypeError('循环引用了'));
}
let called;//控制成功或失败只能调用一次
if(x!==null && (typeof x==='object'||typeof x==='function')){
try{
let then=x.then;
if(typeof then==='function'){
then.call(x,function(y){ //y可能还是一个promise,递归解析,直到返回普通值
if(called)return;
called=true;
resolvePromise(promise2,y,resolve,reject)
},function(err){
if(called)return;
called=true;
reject(err);
});
}else{
resolve(x);
}
} catch (e) {
if (called) return
called = true;
reject(e);
}
} else { // 说明是一个普通值
resolve(x);
}
}
Promise.prototype.then=function(onFufilled,onReject){
onFufilled=typeof onFufilled==='function'?onFufilled:function(value){
return value;
}
onReject=typeof onReject==='function'?onReject:function(err){
throw err;//抛出错误,才会走下个then的失败
}
let self=this;
let promise2;
if(self.status=='pending'){
promise2=new Promise(function(resolve,reject){
self.onResolvedCallbacks.push(function(){
setTimeout(function(){
try{
let x=onFufilled(self.value);
resolvePromise(promise2,x,resolve,reject);
}catch(e){
reject(e)
}
})
});
self.onRejectedCallbacks.push(function(){
setTimeout(function(){
try{
let x=onReject(self.reason);
resolvePromise(promise2,x,resolve,reject);
}catch(e){
reject(e);
}
})
});
})
}
if(self.status=='resolve'){
promise2=new Promise(function(resolve,reject){
setTimeout(function(){
try{
let x=onFufilled(self.value);
resolvePromise(promise2,x,resolve,reject);
}catch(e){
reject(e)
}
})
})
}
if(self.status=='reject'){
promise2=new Promise(function(resolve,reject){
setTimeout(function(){
try{
let x=onReject(self.reason);//这里的x可能是一个普通值,也可能是一个promise,所以写个方法统一处理。
resolvePromise(promise2,x,resolve,reject);
}catch(e){
reject(e);
}
})
})
}
return promise2;
};
Promise.defer = Promise.deferred = function () {
let dfd = {};
dfd.promise = new Promise(function (resolve, reject) {
dfd.resolve = resolve;
dfd.reject = reject;
});
return dfd
}
Promise.all=function(promises){
//promises是一个promise的数组,同时需要返回一个promise
return new Promise(function(resolve,reject){
let arr=[]; //arr是最终返回值的结果集
let i=0;
function processData(index,y){
arr[index]=y;
if(++i===promises.length){
resolve(arr);
}
}
for(let i=0;i<promises.length;i++){ //因为then的时候,for循环已经走了,i值就是最大的,所以这里用let,保证每次i都是都是当前值
promises[i].then(function(y){
processData(i,y);
},function(err){
reject();
})
}
})
}
Promise.race=function(promises){
return new Promise(function(resolve,reject){
for(let i=0;i<promises.length;i++){
promises[i].then(function(data){
resolve(data);
},function(err){
reject(err);
})
}
})
}
Promise.resolve=function(value){
return new Promise(function(resolve,reject){
resolve(value);
})
}
Promise.reject=function(reason){
return new Promise(function(resolve,reject){
reject(reason);
})
}
Promise.prototype.catch = function (callback) {
return this.then(null, callback)
}
Promise原理剖析的更多相关文章
- 30分钟,让你彻底明白Promise原理
前言 前一阵子记录了promise的一些常规用法,这篇文章再深入一个层次,来分析分析promise的这种规则机制是如何实现的.ps:本文适合已经对promise的用法有所了解的人阅读,如果对其用法还不 ...
- Promise 原理
异步:可同时好几件事,互不影响: 同步:按循序一件一件.... 异步好多缺点:.... promise就是解决异步计算的这些缺点的,主要用于: 1.异步计算: 2.可以将异步操作队列化 按期望的顺序 ...
- 原理剖析-Netty之服务端启动工作原理分析(下)
一.大致介绍 1.由于篇幅过长难以发布,所以本章节接着上一节来的,上一章节为[原理剖析(第 010 篇)Netty之服务端启动工作原理分析(上)]: 2.那么本章节就继续分析Netty的服务端启动,分 ...
- 10分钟,让你彻底明白Promise原理
什么是Promise?本代码用定外卖来举例子,让你明白. // 定外卖就是一个Promise,Promist的意思就是承诺// 我们定完外卖,饭不会立即到我们手中// 这时候我们和商家就要达成一个承诺 ...
- ASP.NET Core 运行原理剖析2:Startup 和 Middleware(中间件)
ASP.NET Core 运行原理剖析2:Startup 和 Middleware(中间件) Startup Class 1.Startup Constructor(构造函数) 2.Configure ...
- ASP.NET Core 运行原理剖析1:初始化WebApp模版并运行
ASP.NET Core 运行原理剖析1:初始化WebApp模版并运行 核心框架 ASP.NET Core APP 创建与运行 总结 之前两篇文章简析.NET Core 以及与 .NET Framew ...
- 【Xamarin挖墙脚系列:Xamarin.IOS机制原理剖析】
原文:[Xamarin挖墙脚系列:Xamarin.IOS机制原理剖析] [注意:]团队里总是有人反映卸载Xamarin,清理不完全.之前写过如何完全卸载清理剩余的文件.今天写了Windows下的批命令 ...
- 【Xamarin 跨平台机制原理剖析】
原文:[Xamarin 跨平台机制原理剖析] [看了请推荐,推荐满100后,将发补丁地址] Xamarin项目从喊口号到现在,好几个年头了,在内地没有火起来,原因无非有三,1.授权费贵 2.贵 3.原 ...
- iPhone/Mac Objective-C内存管理教程和原理剖析
http://www.cocoachina.com/bbs/read.php?tid-15963.html 版权声明 此文版权归作者Vince Yuan (vince.yuan#gmail.com)所 ...
随机推荐
- 《从零开始学Swift》学习笔记(Day 70)——Swift与Objective-C混合编程之Swift与Objective-C API映射
原创文章,欢迎转载.转载请注明:关东升的博客 Swift与Objective-C API映射 在混合编程过程中Swift与Objective-C调用是双向的,由于不同语言对于相同API的表述是不同的, ...
- Android TextView使用HTML处理字体样式、显示图片等
一般情况下,TextView中的文本都是一个样式.那么如何对于TextView中各个部分的文本来设置字体,大小,颜色,样式,以及超级链接等属性呢?下面我们通过SpannableString的具体实例操 ...
- linux的简单查找的方法
catalina.out文件查找指定行sed -n 346492p catalina.out 查找第几到第几行sed -n 346200,346692p catalina.out 查找指定内容(不区分 ...
- 虚拟机VMWare安装苹果系统MacOS详细教程(联网设置,全屏插件、文件互传)
运行环境: VMware® Workstation 12 Pro(自行安装,或者用这个) 推荐(下面以10.11.6版本做的教程,但是安装时推荐使用此版本安装然后升级到10.11.6):MacOS X ...
- 简述泛型、用Maven创建Web项目以及在Web项目上整合SpringMVC
表设计 Timestamp列是否取消"根据当前时间戳自动更新" 是否null及默认值选择合理不合理 外键命名规范及更新和删除时的动作是否合理 泛型 类型参数 --允许在外部指定 ...
- WEB状态码
这些状态代码表示临时的响应.客户端在收到常规响应之前,应准备接收一个或多个 1xx 响应. 100 - 继续. 101 - 切换协议. 2xx - 成功 这类状态代码表明服务器成功地接受了客户端请求. ...
- ELK basic---http://udn.yyuap.com/doc/logstash-best-practice-cn/filter/grok.html
http://blog.csdn.net/lgnlgn/article/details/8053626 elasticsearch学习入门 input {stdin{}}filter { grok { ...
- linux下的时间管理概述
2017/6/21 时间这一概念在生活中至关重要,而在操作系统中也同样重要,其在系统中的功能绝不仅仅是给用户提供时间这么简单,内核的许多机制都依赖于时间子系统.但凡是要在某个精确的时间执行某个事件,必 ...
- git学习------> Gitlab如何进行备份恢复与迁移?
前段时间,在某台CenterOS服务器上搭建了Gitlab环境,并且大家陆陆续续的都把代码从svn迁移到了gitlab,但是之前的CenterOS服务器并不是搭建在公司的机房环境,而是搭建在办公室的某 ...
- iftop linux监控工具安装使用
Linux中查看网卡流量工具有iptraf.iftop以及nethogs等,iftop可以用来监控网卡的实时流量(可以指定网段).反向解析IP.显示端口信息等. 安装iftop的命令如下: CentO ...