第一步1.搭建Promise结构
promise起始状态为pending
调用resolve成功为solved 调用reject失败为rejected
返回的值包含 起始状态和值
class Promise {
constructor(executor) {
//先定义初始值
const PromiseState = 'Pending'
const PromiseResult = null
//定义resolve函数
const resolve = (data) => {
this.PromiseState = 'resolved'
this.PromiseResult = data
}
//定义reject函数
const reject = (data) => {
this.PromiseState = 'reject'
this.PromiseResult = data
}
}
executor(resolve, reject)
}
第二步 解决抛出错误问题
try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
第三步 解决状态只能改变一次的问题
if (this.PromiseState !== 'Pending') return;
结合起来看一下 此时只缺少解决多个异步任务的问题
class Promise {
constructor(executor) {
//两个初始值
this.PromiseState = 'Pending'
this.PromiseResult = null
//创建resolve函数
const resolve = (data) => {
//如果状态发生过改变直接返回
if (this.PromiseState !== 'Pending') return;
//改变两个属性值
this.PromiseState = 'resolved'
this.PromiseResult = data
}
//创建reject函数
const reject = (data) => {
//如果状态发生过改变直接返回
if (this.PromiseState !== 'Pending') return;
//改变两个属性值
this.PromiseState = 'rejected'
this.PromiseResult = data
}
//解决抛出错误
try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
}
第四步 添加then方法并添加成功和失败的回调
then(onResolved, onRejected) {
return new Promise((resolve, reject) => {
//成功的回调
if (this.PromiseState == 'resolved') {
onResolved()
}
//失败的回调
if (this.PromiseState == 'rejected') {
onRejected()
}
}
}
第四步 解决异步问题
如果Promise的起始状态为pending 我们需要将成功失败的回调存起来 等状态发生改变再去执行,因为考虑可能有多个then同时出现,所以我们采用数组的方式存起来
this.callback = []
if (this.PromiseState == 'Pending') {
this.callback.push({
onResolved,
onRejected
})
}
//这一步就是遍历回调(这一步是放在 )
this.resolveCallBack.forEach(item => item.onResolved(val));
第五步 解决多个Promise嵌套的情况
//成功的回调
if (this.PromiseState == 'resolved') {
//收集成功回调返回的结果
let result = onResolved(this.PromiseResult)
//如果返回的结果是一个Promise 则再执行一遍then方法 如果不是则返回结果
if (result instanceof Promise) {
result.then(v => { resolve(v) }, r => { reject(r) })
} else {
resolve(result)
}
}
第六步 解决抛出错误
//成功的回调
if (this.PromiseState == 'resolved') {
try {
let result = onResolved(this.PromiseResult)
if (result instanceof Promise) {
result.then(v => { resolve(v) }, r => { reject(r) })
} else {
resolve(result)
}
} catch (e) { reject(e) }
}
整体结合起来看一下
class Promise {
constructor(executor) {
//定义初始值
this.PromiseState = 'Pending'
this.PromiseResult = null
//存放成功的回调
this.resolveCallBack = []
//存放失败的回调
this.rejectCallBack = []
//创建resolve函数
const resolve = (val) => {
//对当前状态进行判断
if (this.PromiseState !== 'Pending') return
//赋值
this.PromiseState = 'resolved'
this.PromiseResult = val
//遍历回调
this.resolveCallBack.forEach(item => item.onResolved(val));
}
//创建reject函数
const reject = (res) => {
//对当前状态进行判断
if (this.PromiseState !== 'Pending') return
//赋值
this.PromiseState = 'rejected'
this.PromiseResult = res
//遍历回调
this.rejectCallBack.forEach(item => item.onRejected(res));
}
try {
executor(resolve, reject)
} catch (error) {
reject(error)
}
}
then(onResolved, onRejected) {
return new Promise((resolve, reject) => {
//成功的回调
if (this.PromiseState == 'resolved') {
try {
let result = onResolved(this.PromiseResult)
if (result instanceof Promise) {
result.then(v => { resolve(v) }, r => { reject(r) })
} else {
resolve(result)
}
} catch (e) { reject(e) }
}
//失败的回调
if (this.PromiseState == 'rejected') {
try {
let result = onRjected(this.PromiseResult)
if (result instanceof Promise) {
result.then(v => { resolve(v) }, r => { reject(r) })
} else {
resolve(result)
}
} catch (e) { reject(e) }
}
//状态未改变
if (this.PromiseState == 'Pending') {
this.resolveCallBank.push( onResolved)
this.rejectCallBank.push( onRejected)
}
})
}
catch方法
catch(onRejected) {
return this.then(undefined, onRejected)
}
其次就是resolved rejected all race 方法 就不拆开了
all和race方法传入的都是一个数组
区别在于 all 全部为成功 返回的结果才为成功 race 返回的值是第一个改变状态的值
static resolve(value) {
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(v => { resolve(v) }, r => { reject(r) })
} else {
resolve(value)
}
})
}
static reject(reason) {
return new Promise((resolve, reject) => {
reject(reason)
})
}
static all = function (array) {
return new Promise((resolve, reject) => {
let num = 0
let arr = []
for (let i = 0; i < array.length; i++) {
array[i].then(v => {
num++
arr[i] = v
if (num == array.length) resolve(arr)
}, r => {
reject(r)
})
}
})
}
static race = function (array) {
return new Promise((resolve, reject) => {
for (let i = 0; i < array.length; i++) {
array[i].then(v => {
resolve(v)
}, r => {
reject(r)
})
}
})
}