想看直接看手写Promise构造函数,可直接翻到最下面的代码
1、基础知识点
-
先讲涉及promise的基础知识点(我只是简略涉及,具体可以去看翻阅MDN文档)
-
Promise是一种处理异步代码(而不会陷入回调地狱)的方式
-
Promise有三种状态:pending(初始状态,待定),fulfilled(表示操作完成),rejected(表示操作失败)
-
它的状态存放在属性[[PromiseState]]中
-
当new一个Promise来生成一个实例对象时,它接收一个回调函数,这个回调函数接收两个参数resolve和reject,这两个参数也是函数,当操作成功完成时调用resolve,操作失败时调用reject
-
调用resolve后,实例对象的状态变为fulffiled
-
调用rejected后,实例函数的状态变为rejected
-
也可以通过抛出异常,来将实例对象的状态变为rejected
-
注意:promise的状态只能修改一次
-
Promise上还存有属性[[PromiseResult]],上面放在异步任务成功或失败的结果,通过resolve函数,或者reject函数修改
-
需要说明的是,Promise中接收的这个回调函数是个立即执行的函数,即称执行函数
-
操作完成,实例对象改变状态后,可以调用then方法或者catch方法。then方法接收两个回调函数,当实例对象的状态是fulfilled的时执行第一个回调函数,当实例对象的状态是rejected时,执行第二个回调函数
-
并且then方法得回调函数其接收的参数便是[[PromiseResult]]上的值
2、相关API
在手写之前,还需要再来说说Promise的几个API的用法,
2.1、Promise(excutor{})
- excutor是一个执行函数,会在你声明Promise时,就在Promise内部立即同步执行,异步操作在执行器中执行
let a = new Promise(()=>{
console.log('1')
})
console.log('2',a)
//最后执行结果
// 1
// 2
//Promise{}
2.2、Promise.prototype.then((value)=>{},(reason)=>{})
- 状态为fulfilled时,调用第一个回调函数
- 状态为rejected时,调用第二个回调函数
- then方法也会返回一个Promise对象
-
- 如果then()return了一个值,那么then返回得Promise将会变为成功状态,并且其[[PromiseResult]]上的值也会变为返回的这个值
-
- 让雨果then()return了一个Promise对象,那么如果这个Promise对象状态是成功的,则then返回一个成功的Promise对象,如果这个Promise对象状态是失败,则tehn返回一个失败的Promise对象。并且其[[PromiseResult]]上的值都相同
2.3、Promise.prototype.catch(reason=>{})
- 只能执行失败的回调函数
2.4、Promise.resolve()
- 该方法属于Promise构造函数上的方法,而不是属于实例对象的方法
- resolve接收一个参数,然后返回一个成功/失败的promise对象
- 如果传入的参数是非promise类型的对象,则返回的结果是状态为成功的promise对象
- 如果传入的参数是一个Promise对象,
-
- 当这个Promise对象的状态是成功时,则返回一个状态为成功的Promise对象,并且其[[PromiseResult]]上的值也相同
-
- 当这个Promise对象的状态是失败时,则返回一个状态为失败的Promise对象,并且其[[PromiseResult]]上的值也相同
2.5、Promise.reject()
- Promise.reject(),该方法属于Promise函数对象的,而不是属于实例对象的。
- 该方法是接受一个参数,然后快速返回一个失败的promise对象
- 并且[[PromiseResult]]上的值就是这个传入的参数
2.6、Pomise.all()
- 该方法属于Promise函数对象的,而不是属于实例对象的。
-
- 它接收一个有Promise对象组成的数组
- 它返回一个新的promise对象,只有所有的promise都成功才成功,只要由一个失败了就直接失败
2.7 Promise.race()
- 该方法属于Promise函数对象的,而不是属于实例对象的。
- 它接收一个由Promise对象组成的数组参数
- 它返回一个新的promise,第一个先完成的Promise的结果状态就是最终的结果状态
3、手写Promise
class Promise {
//构造方法
constructor(executor) {
//初始化状态和结果
let PromiseState = 'pending'
let PromiseResult = null
const context = this
//用于存放回调函数
let callbacks = []
function resolve(value) {
//判断状态是否为pending
if (context.PromiseResult !== 'pending') return
context.PromiseState = 'fulfilled'
context.PromiseResult = value
//执行成功的回调函数
setTimeout(() => {
context.callbacks.forEach(element => {
element.onResolved(value)
});
})
}
function reject(reason) {
if (context.PromiseResult !== 'pending') return
context.PromiseState = 'fulfilled'
context.PromiseResult = reason
//执行成功的回调函数
setTimeout(() => {
context.callbacks.forEach(element => {
element.onResolved(value)
});
})
}
try {
executor(resolve, reject)
} catch (e) {
//抛出异常也可以改变Pormise的状态
reject(e)
}
}
//then方法
then(onResolved, onRejected) {
const context = this
return new Promise((resolve, reject) => {
//封装一个函数
function callback(type) {
//type为onResolved或者onRejected
let result = type(context.PromiseResult)
if (result instanceof Promise) {
result.then(() => {
resolve(result)
}, () => {
reject(result)
})
} else {
resolve(result)
}
}
if (context.PromiseState === 'fulfilled') {
setTimeout(() => {
callback(onResolved)
}, 0)
}
if (context.PromiseState === 'rejected') {
setTimeout(() => {
callback(onRejected)
}, 0)
}
//new Promise()时,里面的异步任务还没有执行完
//故此时状态为pending
if (context.PromiseState == 'pending') {
context.callbacks.push({
onResolved: function () {
callback(onResolved)
},
onRejected: function () {
callback(onRejected)
}
})
}
})
}
//catch方法
//只捕获失败的回调函数
catch(){
return this.then(undefined,onRejected)
}
//添加resolve方法
static resolve(value){
return new Promise((resolve,reject)=>{
if(value instanceof Promise){
value.then((data)=>{
resolve(data)
},(reason)=>{
reject(reason)
})
}else{
return resolve(value)
}
})
}
//添加reject方法
static reject(reason){
return new Promise((resolve,reject)=>{
reject(reason)
})
}
//添加all方法
static all(promises){
//promises是一个由Promise对象组成的数组
if(Object.prototype.toString.call(promises).slice(8,-1)!=='Array'){
return
}
return new Promise((resolve,reject)=>{
let count = 0
let valueList = []
for (let i = 0; i < promises.length; i++) {
promises[i].then((value) => {
count++
valueList[i] = value
//只有promises中所有的对象的状态都为成功时,才返回成功的实例对象
if (count === promises.length) {
resolve(valueList)
}
},(reason)=>{
reject(reason)
})
}
})
}
//添加race方法
static race(promises){
//promises是一个由Promise对象组成的数组
if(Object.prototype.toString.call(promises).slice(8,-1)!=='Array'){
return
}
return new Promise((resolve,reject)=>{
for (let i = 0; i < promises.length; i++) {
promises[i].then((value) => {
//修改返回对象的状态为成功
resolve(value)
}, (reason) => {
reject(reason)
})
}
})
}
}