Promise是异步编程的一种解决方案,比回调函数和事件更合理更强大。编程
原生的promise用法以下:数组
let p=new Promise(function(resolve,reject){
resolve('成功');
//reject('失败');
});
p.then(function(data){
console.log(data);
},function(err){
console.log(err);
});
复制代码
Promise实例中有一个函数,接受两个参数,一个是成功的方法,一个是失败的方法,而后有一个then方法,第一个是成功执行的函数,第二个是失败执行的函数,而且会接收相应的参数。一旦执行成功,就不会再执行失败,反之亦然。promise
function Promise(executor){ //executor是一个执行函数
let self = this;
self.status = 'pending';
self.value = undefined; //默认成功的值
self.reason = undefined; //默认失败的值
function resolve(value){ //成功状态
if(self.status === 'pending'){
self.status = 'resolved';
self.value = value;
}
}
function reject(reason){ //失败状态
if(self.status === 'pending'){
self.status = 'rejected';
self.reason = reason;
}
}
try{
executor(resolve,reject);
}catch(e){ //处理异常状态,传给reject
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);
}
};
module.exports = Promise;
复制代码
首先先定义一个Promise函数,而且接受一个executor执行函数,将resolve和reject传参传进去,定义私有属性status,value,reason。 Promise有三个状态,status用来记录他们: 初始状态为pending 成功状态为resolved 失败状态为rejectedbash
而后使用prototype挂载一个then方法, 方法中要传入一个成功的回掉和一个失败的回掉, 若是成功就调取成功的回掉, 失败就调取失败的回掉异步
最后将函数导出,就实现了一个最基础功能的Promise。异步编程
可是这个Promise仍是一个同步的方法,若是想在代码中使用异步,好比:函数
let p=new Promise(function(resolve,reject){
setTimeout(function(){
resolve('成功');
},1000);
//throw new Error('错误');
});
复制代码
咱们就须要将他变为异步的:ui
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.status = 'resolved';
self.value = value;
self.onResolvedCallbacks.forEach(function(fn){
fn();
});
}
}
function reject(reason){
if(self.status === 'pending'){
self.status = 'rejected';
self.reason = reason;
self.onRejectedCallbacks.forEach(function(fn){
fn();
});
}
}
try{
executor(resolve,reject);
}catch(e){ //处理异常状态,传给reject
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'){
self.onResolvedCallbacks.push(function(){
onFulfilled(self.value);
});
self.onRejectedCallbacks.push(function(){
onRejected(self.reason);
});
}
};
module.exports = Promise;
复制代码
若是他是异步的,咱们就不能在then方法中用status的成功失败状态来判断他走的那,由于then方法执行后有可能params中还没执行resolve或者reject,那么咱们就在Promise实例上再新增onResolvedCallbacks和onRejectedCallbacks两个数组来存放他的回掉,若是执行的是成功,失败就会存默认的undefined。在调用时用forEach循环数组依次知性方法。 原生的Promise还能够then屡次:this
function Promise(executor){
let self = this;
self.status = 'pending';
self.value = undefined;
self.reason = undefined;
self.onResolvedCallbacks= [];
self.onRejectedCallbacks= [];
function resolve(value){
self.status = 'resolved';
self.value = value;
self.onResolvedCallbacks.forEach(function(fn){
fn();
});
}
function reject(reason){
self.status = 'rejected';
self.reason = reason;
self.onRejectedCallbacks.forEach(function(fn){
fn();
});
}
try{
executor(resolve,reject);
}catch(e){
reject(e);
}
};
Promise.prototype.then = function(onFulfilled,onRejected){
let self = this;
let promise2; //实现链式操做
if(self.status === 'resolved'){
promise2 = new Promise(function(resolve, reject){
try{
let x = onFulfilled(self.value);
resolve(x);
}catch(e){
reject(e);
}
});
}
if(self.status === 'rejected'){
promise2 = new Promise(function(resolve, reject){
try{
let x = onRejected(self.reason);
reject(x);
}catch(e){
reject(e);
}
});
}
if(self.status === 'pending'){
promise2 = new Promise(function(resolve, reject){
self.onResolvedCallbacks.push(function(){
try{
let x = onFulfilled(self.value);
resolve(x);
}catch(e){
reject(e);
}
});
self.onRejectedCallbacks.push(function(){
try{
let x = onRejected(self.reason);
reject(x);
}catch(e){
reject(e);
}
});
});
}
return promise2;
}
module.exports = Promise;
复制代码
固然他then的链式调用不会有then属性,因此咱们能够判断Promise每次then都会new一个新的Promise咱们用Promise2来表示,then的时候new一个新的Promise而且return给下一个then。 then中不管是成功的回掉仍是失败的毁掉,只要返回告终果,就会走下一个then中的成功,发生错误才会走下一个then中的失败,then中能够return普通值,也可return一个新的Promise,还有可能return 一个{then:xxx},固然更有promise.then().then.then(function(){});这种奇葩的用法spa
function Promise(executor){
let self = this;
self.status = 'pending';
self.value = undefined;
self.reason = undefined;
self.onResolvedCallbacks= [];
self.onRejectedCallbacks= [];
function resolve(value){
self.status = 'resolved';
self.value = value;
self.onResolvedCallbacks.forEach(function(fn){
fn();
});
}
function reject(reason){
self.status = 'rejected';
self.reason = reason;
self.onRejectedCallbacks.forEach(function(fn){
fn();
});
}
try{
executor(resolve,reject);
}catch(e){
reject(e);
}
};
function resolvePromise(p2,x,resolve,reject){
//1.处理乱写
//2.判断返回的是否是本身
if(p2 === x){
reject(new typeError('循环引用'));
}
//判断x是否是params(判断x是否是object)
let called; //表示是否调用过成功或者失败
if(x !== null || typeof x === 'object' || typeof x === 'function'){
//判断promise只要判断对象中是否有then方法
try{
let then = x.then;
if(typeof then === 'function'){ //then返回的多是{then:xxx},判断then是否是一个函数
then.call(x,function(y){ //成功了之后可能会执行resolve(new Promise())用递归来解决
if(called) return;
called = true;
resolvePromise(p2,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{ //esle普通值
resolve(x);
}
}
Promise.prototype.then = function(onFulfilled,onRejected){ //判断onFulfilled是否是一个函数,不是给他个函数
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : function(value){
return value;
}
onRejected = typeof onRejected === 'function' ? onRejected : function(err){
throw err;
}
let self = this;
let promise2; //实现链式操做
if(self.status === 'resolved'){
promise2 = new Promise(function(resolve, reject){
let x = onFulfilled(self.value);
resolvePromise(promise2,x,resolve,reject);
});
}
if(self.status === 'rejected'){
promise2 = new Promise(function(resolve, reject){
let x = onRejected(self.reason);
resolvePromise(promise2,x,resolve,reject);
});
}
if(self.status === 'pending'){
promise2 = new Promise(function(resolve, reject){
self.onResolvedCallbacks.push(function(){
let x = onFulfilled(self.value);
resolvePromise(promise2,x,resolve,reject);
});
self.onRejectedCallbacks.push(function(){
let x = onRejected(self.reason);
resolvePromise(promise2,x,resolve,reject);
});
});
}
return promise2;
}
module.exports = Promise;
复制代码
咱们就定义一个resolvePromise来处理then中的返回结果,若是返回的是个错误信息,就用try{}catch(){}让他走reject 最后的最后,Promise中能够异步执行代码,then方法中应该也能够实现异步,很简单,只要在相应的位置加上setTimeout就ok了,记得不要忘了加上try{}catch(){}来过滤错误信息而且传到reject中
function Promise(executor){
let self = this;
self.status = 'pending';
self.value = undefined;
self.reason = undefined;
self.onResolvedCallbacks= [];
self.onRejectedCallbacks= [];
function resolve(value){
self.status = 'resolved';
self.value = value;
self.onResolvedCallbacks.forEach(function(fn){
fn();
});
}
function reject(reason){
self.status = 'rejected';
self.reason = reason;
self.onRejectedCallbacks.forEach(function(fn){
fn();
});
}
try{
executor(resolve,reject);
}catch(e){
reject(e);
}
};
function resolvePromise(p2,x,resolve,reject){
//1.处理乱写
//2.判断返回的是否是本身
if(p2 === x){
reject(new typeError('循环引用'));
}
//判断x是否是params(判断x是否是object)
let called; //表示是否调用过成功或者失败
if(x !== null || typeof x === 'object' || typeof x === 'function'){
//判断promise只要判断对象中是否有then方法
try{
let then = x.then;
if(typeof then === 'function'){ //then返回的多是{then:xxx},判断then是否是一个函数
then.call(x,function(y){ //成功了之后可能会执行resolve(new Promise())用递归来解决
if(called) return;
called = true;
resolvePromise(p2,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{ //esle普通值
resolve(x);
}
}
Promise.prototype.then = function(onFulfilled,onRejected){ //判断onFulfilled是否是一个函数,不是给他个函数
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : function(value){
return value;
}
onRejected = typeof onRejected === 'function' ? onRejected : function(err){
throw err;
}
let self = this;
let promise2; //实现链式操做
if(self.status === 'resolved'){
promise2 = new Promise(function(resolve, reject){
setTimeout(function(){
try{
let x = onFulfilled(self.value);
resolvePromise(promise2,x,resolve,reject);
}catch(e){
reject(e);
}
})
});
}
if(self.status === 'rejected'){
promise2 = new Promise(function(resolve, reject){
setTimeout(function(){
try{
let x = onRejected(self.reason);
resolvePromise(promise2,x,resolve,reject);
}catch(e){
reject(e);
}
})
});
}
if(self.status === 'pending'){
promise2 = new Promise(function(resolve, reject){
self.onResolvedCallbacks.push(function(){
setTimeout(function(){
try{
let x = onFulfilled(self.value);
resolvePromise(promise2,x,resolve,reject);
}catch(e){
reject(e);
}
})
});
self.onRejectedCallbacks.push(function(){
setTimeout(function(){
try{
let x = onRejected(self.reason);
resolvePromise(promise2,x,resolve,reject);
}catch(e){
reject(e);
}
})
});
});
}
return promise2;
}
module.exports = Promise;
复制代码