先上代码为敬
function TimeCD(times,delay){
//初始化参数
this._init = ()=>{
clearTimeout(this.timer)
this.times = times
this.timer = null
this.init = null
}
this._init()
// 开始倒计时
TimeCD.prototype.start = (operation)=>{
if(!this.init){
this.init = true
eval(operation)
}
return new Promise((resolve,reject)=>{
try {
if(this.times>0){
--this.times
this.timer = setTimeout(()=>{
eval(operation)
resolve(this.start(operation))
},delay)
}else{
this._init()
resolve(true)
}
} catch (error) {
reject(error)
}
})
}
// 结束倒计时
TimeCD.prototype.end = (operation)=>{
eval(operation)
}
// 停止倒计时
TimeCD.prototype.stop = ()=>{
this._init()
}
}
const test =new TimeCD(3,1000)
test.start("console.log('倒计时开始'+ this.times)").then(res=>{
test.end("console.log('倒计时结束')")
})
控制台打印结果见图
这里用到了promise
来阻塞end
方法的执行。还有个小芝士
是promise
存在嵌套的话,最里面的promise
的then
方法在外部是最先调用的哈(具体看下面解释)。
代码看完了,然后我们开始聊一聊promise
决议的问题
resolve(value)
,其中value
参数的值有三种,分别是
- value(value是不具有then方法的对象或者根本不是个对象)
- promise
- thenable
1. resolve参数为value
返回一个新的promise
对象,promise
的状态就是 fulfilled
用人话说就是promise
决议的值就是value,在then
方法中可以获取到value
值
2. resolve参数为 promise
const p1 = new Promise((res,rej)=>{
res(true)
})
const p2 = new Promise((res,rej)=>{
res(p1)
})
const p3 = new Promise((res,rej)=>{
res(p2)
})
直接看例子 p3 resolve p2,p2 resolve p1,p1 resolve 一个 value
,再看看输出结果
1)其实是这么一个流程滴!
- P3 在
resolve
的时候 发现value
和值居然是一个promise
实例,于是 P3会返回P2实例,并且等待P2状态改变且传递给P3 - 但是P2在
resolve
的时候value
的值居然也是一个promise
,这可真是雀食了,于是 P2 也只能返回 P1实例,等待P1的状态发生改变 - P1在
resolve
的时候,发现resolve
的值是一个原始数据,于是P1的状态直接变成了fulfilled
,P1将自己的状态传递给P2,P2再将状态传递给P3。于是P3自己的状态已经 改变了。
2)没懂的话别急,再忍耐一下,我还有个栗子
//3秒之后 决议失败
const p1 = new Promise(function (resolve, reject) {
setTimeout(() => reject(new Error('fail')), 3000)
})
//1秒钟后决议成功
const p2 = new Promise(function (resolve, reject) {
setTimeout(() => resolve(p1), 1000)
})
//
p2.then(result => console.log(result))
.catch(error => console.log(error))
p2的状态在 1 秒之后改变,resolve方法返回的是p1。由于p2返回的是另一个 Promise,导致p2自己的状态无效了,由p1的状态决定p2的状态。所以,后面的then语句都变成针对后者(p1),导致触发catch方法指定的回调函数。
这里的参考文章,大噶有空可以去康康
总结:当resolve
的参数是promise
的时候,会返回这个promise
实例,并且状态会跟随返回来的promise
的状态
3.resolve参数为thenable
请你们吃个栗子先
let thenable = {
then: function(resolve, reject) {
resolve('参数类型是thenable');
}
};
let p1 = new Promise((res,rej)=>{
res(thenable)
})
p1.then((res)=> {
console.log(res); // 参数类型是thenable
});
p1的resolve
里面是一个具有then
方法的对象,Promise.resolve方法会将这个对象转为 Promise 对象,然后就立即执行thenable对象的then方法。
值得注意的是,这里只有当 then方法执行后,p1的状态才会发生改变。随后调用then的回调函数
通过一个倒计时函数让我回想起了PromiseA+规范,今天终于好好研究了一番,也算是对自己的一种查缺补漏,下回合我们再来好好聊一聊PromiseA+规范里面的细则。
欢迎大家对本文指出疑点或留言私信交流