<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Promise</title>
</head>
<body>
<script>
// Promise测试
//resolve 解决 函数类型的数据
//reject 拒绝 函数类型的数据
const p=new Promise((resolve,reject)=>{
//设置定时器,弹出一个对话框
//隔两秒,弹出一个对话框
var i=1;
if(i==0)
{
//成功状态的回调函数
resolve(i);//将promise对象的状态设置为成功
}
else
{
//失败状态的回调函数
reject(i);//将promise对象的状态设置为失败
}
});
//调用then方法
//这里对应成功和失败的回调函数,可以接收参数
p.then((value)=>
{
alert("成功原因:"+value);
},(reason)=>{
alert("失败原因:"+reason);
});
</script>
</body>
</html>
<script>
//引入fs的模块
const fs=require('fs');
fs.readFile('dhy.txt',(err,data)=>{
//出错,则抛出错误
if(err)
throw err;
//否则输出文件内容
console.log(data);
});
//采用promise封装fs文件操作
const p=new Promise((reslove,reject)=>{
fs.readFile('dhy.txt',(err,data)=>{
//出错,则抛出错误
if(err) reject(err);
//否则输出文件内容
reslove(data);
});
});
p.then(value=>{
alert(data);
},reason=>{
alert(reason);
})
</script>
const p=new Promise((reslove,reject)=>
{
$.ajax({
urL: "dhy",
success: reslove(data),
error: reject()
});
});
p.then(value=>{
alert(data);
},
reason=>{
alert("失败了");
})
封装后,返回一个promise对象
promise执行器函数中的reslove和reject函数的执行,会改变promise对象的状态,一个是成功,一个是失败,如果没执行者两个函数,那还是未决定状态
在创建promise的时候,同步执行执行器函数
如果传入的promise对象是成功,则外面也成功,如果是失败的,则外面也失败
reject永远都只会返回失败的promise对象,即使参数传递的promise对象是成功的
如果都成功了,返回的结果就是所有promise对象的结果数组集合
其中有一个promise对象失败了,那么返回的结果集就是失败的promise对象的结果集
先指定回调的情况有ajax异步请求,定时器等等…
不管谁先谁后,回调函数获取到数据,都是在reslove和reject函数执行后,才能获取到
即回调函数需要在reslove和reject函数执行完毕后,才会执行
const p=new Promise((reslove,reject)=>
{
//3秒后执行
setTimeout(()=>{
reslove("成功了");
},3000);
});
p.then(value=>{
console.log(value);
},
reason=>{
alert("失败了");
})
等待了3秒后,才打印出来
const p=new Promise((reslove,reject)=>
{
reslove("成功了");
});
var ret=p.then(value=>{
},
reason=>{
alert("失败了");
})
alert(ret);
then方法返回值,默认是调用then方法的promise对象
成功,但是无返回值
const p=new Promise((reslove,reject)=>
{
reslove("成功了");
});
var ret=p.then(value=>
{
//1.抛出错误
throw "出现异常,终止程序";
},
reason=>{
alert("失败原因:" +reason);
})
alert(ret);
alert先执行,然后抛出异常,此时返回的是调用的promise对象,返回的结果是异常结果
const p=new Promise((reslove,reject)=>
{
reslove("成功了");
});
var ret=p.then(value=>
{
//返回结果是非promise类型的对象
return "大忽悠";
},
reason=>{
alert("失败原因:" +reason);
})
console.log(ret);
返回的结果就是大忽悠
只要返回值不是一个promise对象,那么返回的promise对象的状态就永远是成功状态,抛异常除外
const p=new Promise((reslove,reject)=>
{
reslove("大忽悠");
});
var ret=p.then(value=>
{
return new Promise((reslove,reject)=>{
reslove("嘿嘿,成功了");
});
},
reason=>{
alert("失败原因:" +reason);
})
console.log(ret);
返回的结果对应的是返回的promise对象的结果,状态也对应返回的promise对象的状态
const p=new Promise((reslove,reject)=>
{
reslove("1");
});
p.then(value=>
{
console.log(value);
return new Promise((reslove,reject)=>{
reslove("2");
});
})
//then返回的是promise对象的状态和结果由new出来的那个promise对象决定
//链式调用
.then(value=>{
console.log(value);
return "3"
})
//then返回的promise对象的状态为成功,结果为3
//链式调用
.then(value=>{
console.log(value);
})
//此时上面的then没有返回值,返回结果是未定义,状态是未决;
.then(value=>{
console.log(value);
});
const p=new Promise((reslove,reject)=>
{
reslove("1");
});
p.then(value=>
{
console.log(value);
return new Promise((reslove,reject)=>
{
reslove("2");
});
})
.then(value=>{
throw "发生异常";
})
.then(value=>{
console.log(value);
})
.catch(reason=>{
console.log("错误:"+reason);
})
const p=new Promise((reslove,reject)=>
{
reslove("1");
});
p.then(value=>
{
console.log(value);
return new Promise((reslove,reject)=>
{
//也是抛出错误,直接执行最后的catch语句,接收异常
reject("凉凉");
});
})
.then(value=>{
throw "发生异常";
})
.then(value=>{
console.log(value);
})
.catch(reason=>{
console.log("错误:"+reason);
})
注意:如果最后没有console.log(“错误:”+reason);这种打印错误语句,那么链式回调中的错误是不会有任何输出结果的
只有最开始的promise对象成功执行以后,才有下面的成功回调函数的链式调用执行,否则不会执行成功回调函数的链式调用
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Promise</title>
</head>
<body>
<script src="http://code.jquery.com/jquery-2.0.0.min.js"></script> <script src="http://code.jquery.com/jquery-2.0.0.min.js"></script>
<script>
//自定义promise
//声明构造函数
function Promise(executor)
{
//添加属性
//当前Promise对象的状态
this.PromiseState="pending";
//当前Promise对象的返回值
this.PromiseResult=null;
//保存异步回调函数的属性
this.callbacks=[];//保存所有回调函数
//保存实例对象的this值
const self=this;
//reslove函数
function reslove(data){
//当前函数里面的this对象默认指向window
//promise对象的状态只能修改一次
//最开始是pending状态
if(self.PromiseState!="pending")
return;
//1.修改对象的状态
self.PromiseState="fulfilled";//和resloved意思一样,都代表成功
//2.设置对象的返回值
self.PromiseResult=data;
//调用异步的回调函数
//首先判断是否是异步回调
//遍历调用回调数组里面每个成功的回调函数
//执行回调函数是异步的
setTimeout(()=>{
self.callbacks.forEach(item=>{
//调用成功的回调函数,参数是PromiseResult
item.onResloved(data);
});
})
};
//reject函数
function reject(data){
//注意this的指向
//promise对象的状态只能修改一次
//最开始是pending状态
if(self.PromiseState!="pending")
return;
//1.修改对象的状态
self.PromiseState="rejected";
//2.设置对象的返回值
self.PromiseResult=data;
//调用异步的回调函数
//首先判断是否是异步回调
//遍历调用回调数组里面每个成功的回调函数
//执行回调函数是异步的
setTimeout(()=>{
self.callbacks.forEach(item=>{
//调用成功的回调函数,参数是PromiseResult
item.onRejected(data);
});
})
};
//throw抛出异常,也会改变promise对象的状态
try{
//同步调用执行器函数
executor(reslove,reject);
}
//这里e的值就是throw "错误" ==》字符串的值
catch(e){
//修改promise对象的状态为失败
reject(e);
}
}
//添加then方法---then方法需要是异步执行的,即等其他代码执行完毕之后再执行
Promise.prototype.then=function(onResloved,onRejected)
{
//实现异常穿透
//判断回调函数的参数
//then方法第二个参数没填,但是当前promise对象状态是失败的,必须走第二个方法
if(typeof onRejected != 'function')
{
onRejected=reason =>{
throw reason;
}
}
//如果第一个参数没传
if(typeof onResloved != 'function')
{
onResloved=value => value;//等价于return value
}
//调用回调函数
//当前函数this的指向是调用当前函数的Promise对象
var self=this;
//then方法的返回值是promise对象--箭头函数中的this指向外层代码块的this
return new Promise((reslove,reject)=>
{
//封装函数---this指向window
function callback(type)
{
try
{
var ret=type(self.PromiseResult);
if(ret instanceof Promise)
{
ret.then(v=>{
reslove(v);
},
r=>{
reject(r);
})
}
else
{
reslove(ret);
}
}
//给回调函数中传入的两个函数进行处理
if(this.PromiseState==="fulfilled")
{
//调用封装的函数
//定时器包裹,让其可以异步执行
setTimeout(()=>{
callback(onResloved);
});
// //如果出现异常
// try
// {
// //给成功的函数传入实参---即value值
// //即promiseResult
// var ret=onResloved(this.PromiseResult);
// //获取回调函数的执行结果---判断回调函数的返回值
// //判断是什么类型
// if(ret instanceof Promise)
// {
// //如果是promise对象
// //判断成功回调函数返回的promise的状态值和结果
// //这里直接调用成功回调函数返回的promise对象的回调函数
// //如果返回的promise对象状态为成功,
// //那么其在回调函数就会执行成功的回调函数
// ret.then(v=>{
// //返回的对象状态是成功的,设置我们当前then返回返回的对象也是成功的
// //成功的返回结果就是返回的对象的成功结果
// reslove(v);
// },
// r=>{
// //同理
// reject(r);
// })
// }
// else
// {
// //结果的对象状态为成功
// //设置当前then的回调函数返回的promise对象状态为成功,
// //结果为成功回调函数的执行结果
// reslove(ret);
// }
// }
// catch(e)
// {
// //设置返回的promise对象的状态为失败,结果为异常抛出的信息
// reject(e);
// }
}
if(this.PromiseState==="rejected")
{
//定时器包裹,让其可以异步执行
setTimeout(()=>{
callback(onRejected);
});
//给失败的函数传入实参---即reason值
//即promiseResult
// try{
// var ret=onRejected(this.PromiseResult);
// if(re instanceof Promise)
// {
// if(ret instanceof Promise)
// {
// ret.then(v=>
// {
// reslove(v);
// },
// r=>
// {
// reject(r);
// })
// }
// else
// {
// reslove(ret);
// }
// }
// catch(e)
// {
// reject(e);
// }
}
//对异步任务回调进行处理
//判断当前promise对象的状态
//如果为pending则为异步回调
if(this.PromiseState==="pending")
{
//异步修改状态,then结果返回设置
//保存回调函数--等待异步操作完毕后,执行回调
var len=this.callbacks.push({
//对象的方法,this绑定的是当前匿名对象
onResloved: function()
{
callback(onResloved);
// //异常处理
// try{
// //执行成功的回调函数
// let result=onResloved(self.PromiseResult);
// //判断类型,确认返回值
// if(result instanceof Promise)
// {
// //返回的结果和状态和回调获得的promise对象一致
// result.then(v=>{
// reslove(v);
// },r=>{
// reject(r);
// });
// }
// else
// {
// //如果返回类型不是promise对象,那么当前then方法返回的值就是result
// reslove(result);
// }
// }
// catch(e)
// {
// reject(e);
// }
},
onRejected: function()
{
callback(onRejected);
//注意点: 一开始调用then方法的promise对象的状态和then方法返回的对象的状态
//没有太大联系,then方法返回的promise对象的状态取决于then方法的返回值
// try{
// //执行成功的回调函数
// let result=onRejected(self.PromiseResult);
// //判断类型,确认返回值
// if(result instanceof Promise)
// {
// //返回的结果和状态和回调获得的promise对象一致
// result.then(v=>{
// reslove(v);
// },r=>{
// reject(r);
// });
// }
// else
// {
// //如果返回类型不是promise对象,那么当前then方法返回的值就是result
// reslove(result);
// }
// }
// catch(e)
// {
// reject(e);
// }
}
});
}
});
}
//添加catch方法
Promise.prototype.catch=function(onRejected)
{
return then(undefined,onRejected);
}
//添加reslove方法实现---返回的promise状态有传入的值决定
Promise.reslove=function(value)
{
//返回promise对象
return new Promise((reslove,reject)=>
{
if(value instanceof Promise)
{
value.then(v=>{
reslove(v);
},
r=>{
reject(r);
})
}else
{
reslove(value);
}
})
}
//添加reject方法实现---无论传入什么值,都为失败的状态
Promise.reject=function(reason)
{
//返回promise对象
return new Promise((reslove,reject)=>
{
reject(reason);
});
}
//all方法的实现
Promise.all=function(promises)
{
return new Promise((reslove,reject)=>
{
//数组里面传入的promise对象都为真,最后返回的promise状态才为真
//遍历
let count=0;
let arr=[];
for(let i=0;i<promises.length;i++)
{
promises[i].then(v=>
{
//成功
count++;
//将当前成功的promise对象放入数组中
arr[i]=v;
//判断是否都成功了
if(count==promises.length)
{
reslove(arr);
}
},r=>
{
//失败
reject(r);
});
}
}
);
}
//race方法实现---接收一个promises数组
//返回promise对象,状态有数组里面最先改变状态的promise对象决定
Promise.race=function(promises)
{
return new Promise((reslove,reject)=>
{
let count=0;
let arr=[];
for(let i=0;i<promises.length;i++)
{
//promise对象的状态只能修改一次,其余的修改不会生效
//只有状态为pending,才能修改状态
promises[i].then(v=>
{
//修改返回对象的状态为成功
reslove(v);
},r=>
{
//修改返回对象的状态为失败
reject(r);
});
}
}
);
}
/----测试代码----//
let p=new Promise((reslove,reject)=>{
//这里状态只会改变一次,因此下面三条状态改变语句,只有第一条会生效
/* reslove("成功");
reject("失败");
reslove("再次成功"); */
//测试异步回调
setTimeout(()=>{
reslove("异步调用函数成功了");
},1000);
});
//测试回调函数---从原型对象中获取到then函数对象
//测试是否会执行全部的回调函数
p.then(value=>
{
console.log(value);
},reason=>
{
console.log(reason);
});
p.then(value=>
{
console.log(value);
},reason=>
{
console.log(reason);
});
console.log(p);
</script>
</body>
</html>
class Promise
{
//构造方法
constructor(executor)
{
//添加属性
//当前Promise对象的状态
this.PromiseState="pending";
//当前Promise对象的返回值
this.PromiseResult=null;
//保存异步回调函数的属性
this.callbacks=[];//保存所有回调函数
//保存实例对象的this值
const self=this;
//reslove函数
function reslove(data){
//当前函数里面的this对象默认指向window
//promise对象的状态只能修改一次
//最开始是pending状态
if(self.PromiseState!="pending")
return;
//1.修改对象的状态
self.PromiseState="fulfilled";//和resloved意思一样,都代表成功
//2.设置对象的返回值
self.PromiseResult=data;
//调用异步的回调函数
//首先判断是否是异步回调
//遍历调用回调数组里面每个成功的回调函数
//执行回调函数是异步的
setTimeout(()=>{
self.callbacks.forEach(item=>{
//调用成功的回调函数,参数是PromiseResult
item.onResloved(data);
});
})
};
//reject函数
function reject(data){
//注意this的指向
//promise对象的状态只能修改一次
//最开始是pending状态
if(self.PromiseState!="pending")
return;
//1.修改对象的状态
self.PromiseState="rejected";
//2.设置对象的返回值
self.PromiseResult=data;
//调用异步的回调函数
//首先判断是否是异步回调
//遍历调用回调数组里面每个成功的回调函数
//执行回调函数是异步的
setTimeout(()=>{
self.callbacks.forEach(item=>{
//调用成功的回调函数,参数是PromiseResult
item.onRejected(data);
});
})
};
//throw抛出异常,也会改变promise对象的状态
try{
//同步调用执行器函数
executor(reslove,reject);
}
//这里e的值就是throw "错误" ==》字符串的值
catch(e){
//修改promise对象的状态为失败
reject(e);
}
}
//then方法的封装
then(onResloved,onRejected)
{
//实现异常穿透
//判断回调函数的参数
//then方法第二个参数没填,但是当前promise对象状态是失败的,必须走第二个方法
if(typeof onRejected != 'function')
{
onRejected=reason =>{
throw reason;
}
}
//如果第一个参数没传
if(typeof onResloved != 'function')
{
onResloved=value => value;//等价于return value
}
//调用回调函数
//当前函数this的指向是调用当前函数的Promise对象
var self=this;
//then方法的返回值是promise对象--箭头函数中的this指向外层代码块的this
return new Promise((reslove,reject)=>
{
//封装函数---this指向window
function callback(type)
{
try
{
var ret=type(self.PromiseResult);
if(ret instanceof Promise)
{
ret.then(v=>{
reslove(v);
},
r=>{
reject(r);
})
}
else
{
reslove(ret);
}
}
//给回调函数中传入的两个函数进行处理
if(this.PromiseState==="fulfilled")
{
//调用封装的函数
//定时器包裹,让其可以异步执行
setTimeout(()=>{
callback(onResloved);
});
// //如果出现异常
// try
// {
// //给成功的函数传入实参---即value值
// //即promiseResult
// var ret=onResloved(this.PromiseResult);
// //获取回调函数的执行结果---判断回调函数的返回值
// //判断是什么类型
// if(ret instanceof Promise)
// {
// //如果是promise对象
// //判断成功回调函数返回的promise的状态值和结果
// //这里直接调用成功回调函数返回的promise对象的回调函数
// //如果返回的promise对象状态为成功,
// //那么其在回调函数就会执行成功的回调函数
// ret.then(v=>{
// //返回的对象状态是成功的,设置我们当前then返回返回的对象也是成功的
// //成功的返回结果就是返回的对象的成功结果
// reslove(v);
// },
// r=>{
// //同理
// reject(r);
// })
// }
// else
// {
// //结果的对象状态为成功
// //设置当前then的回调函数返回的promise对象状态为成功,
// //结果为成功回调函数的执行结果
// reslove(ret);
// }
// }
// catch(e)
// {
// //设置返回的promise对象的状态为失败,结果为异常抛出的信息
// reject(e);
// }
}
if(this.PromiseState==="rejected")
{
//定时器包裹,让其可以异步执行
setTimeout(()=>{
callback(onRejected);
});
//给失败的函数传入实参---即reason值
//即promiseResult
// try{
// var ret=onRejected(this.PromiseResult);
// if(re instanceof Promise)
// {
// if(ret instanceof Promise)
// {
// ret.then(v=>
// {
// reslove(v);
// },
// r=>
// {
// reject(r);
// })
// }
// else
// {
// reslove(ret);
// }
// }
// catch(e)
// {
// reject(e);
// }
}
//对异步任务回调进行处理
//判断当前promise对象的状态
//如果为pending则为异步回调
if(this.PromiseState==="pending")
{
//异步修改状态,then结果返回设置
//保存回调函数--等待异步操作完毕后,执行回调
var len=this.callbacks.push({
//对象的方法,this绑定的是当前匿名对象
onResloved: function()
{
callback(onResloved);
// //异常处理
// try{
// //执行成功的回调函数
// let result=onResloved(self.PromiseResult);
// //判断类型,确认返回值
// if(result instanceof Promise)
// {
// //返回的结果和状态和回调获得的promise对象一致
// result.then(v=>{
// reslove(v);
// },r=>{
// reject(r);
// });
// }
// else
// {
// //如果返回类型不是promise对象,那么当前then方法返回的值就是result
// reslove(result);
// }
// }
// catch(e)
// {
// reject(e);
// }
},
onRejected: function()
{
callback(onRejected);
//注意点: 一开始调用then方法的promise对象的状态和then方法返回的对象的状态
//没有太大联系,then方法返回的promise对象的状态取决于then方法的返回值
// try{
// //执行成功的回调函数
// let result=onRejected(self.PromiseResult);
// //判断类型,确认返回值
// if(result instanceof Promise)
// {
// //返回的结果和状态和回调获得的promise对象一致
// result.then(v=>{
// reslove(v);
// },r=>{
// reject(r);
// });
// }
// else
// {
// //如果返回类型不是promise对象,那么当前then方法返回的值就是result
// reslove(result);
// }
// }
// catch(e)
// {
// reject(e);
// }
}
});
}
});
}
//catch方法
catch(onRejected)
{
return then(undefined,onRejected);
}
//添加reslove方法,该方法属于类,而不属于对象
static reslove(value)
{
//返回promise对象
return new Promise((reslove,reject)=>
{
if(value instanceof Promise)
{
value.then(v=>{
reslove(v);
},
r=>{
reject(r);
})
}else
{
reslove(value);
}
})
}
//添加reject方法
static reject(reason)
{
//返回promise对象
return new Promise((reslove,reject)=>
{
reject(reason);
});
}
//添加all方法
static all(promises)
{
return new Promise((reslove,reject)=>
{
//数组里面传入的promise对象都为真,最后返回的promise状态才为真
//遍历
let count=0;
let arr=[];
for(let i=0;i<promises.length;i++)
{
promises[i].then(v=>
{
//成功
count++;
//将当前成功的promise对象放入数组中
arr[i]=v;
//判断是否都成功了
if(count==promises.length)
{
reslove(arr);
}
},r=>
{
//失败
reject(r);
});
}
}
);
}
//添加race方法
static race(promises)
{
return new Promise((reslove,reject)=>
{
let count=0;
let arr=[];
for(let i=0;i<promises.length;i++)
{
//promise对象的状态只能修改一次,其余的修改不会生效
//只有状态为pending,才能修改状态
promises[i].then(v=>
{
//修改返回对象的状态为成功
reslove(v);
},r=>
{
//修改返回对象的状态为失败
reject(r);
});
}
}
);
}
}
和then回调方法返回规则一致
当返回非promise对象时,返回值就为对应的非promise类型数据
如果返回promise类型对象,那么返回结果和状态就由返回的promise对象来决定
打印结果依次为:OK, 20
如果promise对象是失败的,则需要通过try…catch语句来获取失败的值,通过await获取报错
定时器中的代码会放在任务队列中,等其他代码执行完毕之后再执行
setTimeout本身是异步的,不指定延时时间的话,就实现了代码变为异步了