首先需要注意的是Promise会有三个状态-PENDING、RESOLVED、REJECTED,
其次,Promise是异步的,并且只能改变一次。
const PENDING = 'pending'
const RESOLVED = 'resolved'
const REJECTED = 'rejected'
function Promise(excutor){
const self = this
self.status = PENDING
self.data = null
self.callback = []
function resolve(value){
//只有状态为PENDING,才可以改变状态
if(self.status !== PENDING) return
//改变状态
self.status = RESOLVED
//储存数据
self.data = value
//执行回调:这里比较难理解的是如果先执行resolve()函数,而还未定义回调时,此时是什么情况?
//定时器模拟异步
setTimeout(()=>{
self.callbacks.forEach(e=>e.onResolved(value))
})
}
function rejected(reason){
if(self.status !== PENDING) return
self.status = REJECTED
self.data = reason
setTimeout(()=>{
self.callbacks.forEach(e=>e.onRejected(reason))
})
}
try{
excutor(resolve,reject)
}catch(error){
reject(error)
}
}
//注意的是:then函数返回的是Promise对象或者非Promise值
//如果为非Promise对象,则状态一律为Resolved
//如果是Promise对象,则状态由该对象的状态所决定
//另外,特殊情况: throw error--此时状态为onRejected。
Promise.then = function(OnResolved,onRejected){
const self = this
function handleCallback(type){
try{
//状态由返回值决定--平时一般咱们用的都是无返回值,即返回为undefined--非Promise对象
const result = type(self.data)
if(result instanceof Promise){
//promise对象:利用then函数看该对象执行的是resolve或者reject,就可以得到状态了
result.then(resolve,reject)
}else{
//非Promise对象
resolve(result)
}
}catch(error){
//异常
reject(error)
}
}
return new Promise((resolve,reject)=>{
if(self.status === RESOLVED){
setTimeout(()=>{
handleCallback(onResolved)
})
}else if(self.status === REJECTED){
setTimeout(()=>{
handleCallback(onRejected)
})
}else{
//需要注意的是如果为pending状态,我们需要将回调传到callbacks中。
//个人理解:Promise和then搭配使用,利用微任务与宏任务的关系,可以让push会在forEach先执行,所以Promise和then搭配使用会更优哦~~~~
self.callbacks.push({
onResolved: value => handleCallback(OnResolved),
onRejected: reason => handleCallback(onRejected)
})
}
//但是事实上,ES6的Promise中也可以先执行resolve(),再通过then定义该函数。
//这是Promise默认的约定--此回调函数也会被调用。
最后挂上MDN关于Promise的官网:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Using_promises
虽然我写的这个promise可以实现正常使用,但是最后这个默认的约定这块,我思考了很久没有明白,希望看见的大佬们可以给我讲解一下,感谢!!!