/*
* prmoise接收一个参数,执行器参数
* 执行器参数接收两个参数:resolve,reject
* promise有三种状态,pending,fulfilled,rejected
* 状态一旦改变,不可逆,只能是pending-->fulfilled和pending-->rejected
* 有状态,有保存数据的变量
* */
function handle(promise, callback, value, resolve, reject) {
try {
let result = callback(value)
// if (promise === result) {
// throw new TypeError('Chaining cycle detected') // 在当前的promise里不允许返回当前的pomise
// }
if (result instanceof MyPromise) {
result.then(resolve, reject) // result是一个promise实例调用then来判断当前promise的状态,
} else {
resolve(result) // 如果返回的不是promise,则直接改成resolve状态
}
} catch (e) {
reject(e)
}
}
class MyPromise {
static PENDING = 'pending'
static FULFILLED = 'fulfilled'
static REJECTED = 'rejected'
constructor(executor) { // 接收一个参数
this.status = MyPromise.PENDING // 保存状态
this.value = undefined // 保存数据
this.callbacks = [] // 当异步执行executor时,执行then的时候promise的状态还是pending,所以这时候需要把then的两个回调函数存起来
/*
* 执行resolve需要做的事:
* --改变promise的状态为fulfilled
* --把值传出去
* --只有在pending状态下时才能改变值
* --异步执行then的回调
* */
let resolve = (value) => {
if (this.status === MyPromise.PENDING) {
this.status = MyPromise.FULFILLED
this.value = value
if (this.callbacks.length) { // 执行then的回调函数是异步执行的
setTimeout(() => {
this.callbacks.map(cb => cb.onFulfilled(value))
})
}
}
}
/*
* 执行reject需要做的事:
* --改变promise的状态为rejected
* --把值传出去
* --只有在pending状态下时才能改变值
* --异步执行then的回调
* */
let reject = (reason) => {
if (this.status === MyPromise.PENDING) {
this.status = MyPromise.REJECTED
this.value = reason
if (this.callbacks.length) { // 执行then的回调函数是异步执行的
setTimeout(() => {
this.callbacks.map(cb => cb.onRejected(reason))
})
}
}
}
try {
executor(resolve, reject) // 接收两个函数参数
} catch (e) { // 如果出错直接调用reject
reject(e)
}
}
/*
* then需要做的事:
* --接收两个函数参数
* --返回一个新的promise
* --当传入的形参不是函数时,新声明一个函数并将数据返回
* --then的链式调用
* --判断当前的promise是什么状态,fulfilled状态执行第一个回调函数onFulfilled
* rejected状态执行第二个回调函数
* --onFulfilled和onRejected可能返回一个新的promise或者一个普通值
* then的状态是根据onFulfilled, onRejected的执行结果来决定的
* */
then(onFulfilled, onRejected) {
// 先判断传入的是不是函数,不是直接返回
if (typeof onFulfilled !== 'function') {
onFulfilled = () => this.value
}
if (typeof onRejected !== 'function') {
onRejected = () => {
throw this.value
} // 如果是失败的,那返回的也要是失败的
}
// 返回一个新的promise
let promise = new MyPromise((resolve, reject) => {
// 判断当前promise的状态
/*
* 为pending时,说明执行到then的时候promise的状态还没有改变,也就是改变promise的状态的
* 语句在定时器里执行的,所以放在任务队列里了,所以把then里的回调函数存起来,等定时器的时间到了
* 执行resolve或者reject的时候,把then的回调函数依次执行
* */
if (this.status === MyPromise.PENDING) {
this.callbacks.push({
// 在resolve里遍历执行的时候把this.value传过来了,所以这里的value就是reslove括号里的值
onFulfilled: value => { // onFulfilled也就是then的第一个回调函数,可能返回一个promise,所以要分两种情况
handle(promise, onFulfilled, value, resolve, reject)
// try {
// let result = onFulfilled(value)
// if (result instanceof MyPromise) {
// result.then(resolve, reject) // result是一个promise实例调用then来判断当前promise的状态,
// } else {
// resolve(value) // 如果返回的不是promise,则直接改成resolve状态
// }
// } catch (e) {
// reject(e)
// }
},
onRejected: reason => {
handle(promise, onRejected, reason, resolve, reject)
// try {
// let result = onRejected(reason)
// if (result instanceof MyPromise) {
// result.then(resolve, reject) // result是一个promise实例调用then来判断当前promise的状态,
// } else {
// resolve(reason) // 如果返回的不是promise,则直接改成resolve状态
// }
// } catch (e) {
// reject(e)
// }
}
})
}
/*
* 为fulfilled状态时,说明是先改变了promise的状态,已经知道了当前promise的状态
* 所以直接调用then的第一个回调函数,但是then的第一个回调函数onFulfilled返回的可能是一个promise
* 所以需要判断下,也是异步执行的
* */
if (this.status === MyPromise.FULFILLED) {
setTimeout(() => {
handle(promise, onFulfilled, this.value, resolve, reject)
// try {
// let result = onFulfilled(this.value)
// if (result instanceof MyPromise) {
// result.then(resolve, reject) // result是一个promise实例调用then来判断当前promise的状态,
// } else {
// resolve(result) // 如果返回的不是promise,则直接改成resolve状态
// }
// } catch (e) {
// reject(e)
// }
})
}
if (this.status === MyPromise.REJECTED) {
setTimeout(() => {
try {
handle(promise, onRejected, this.value, resolve, reject)
// let result = onRejected(this.value)
// if (result instanceof MyPromise) {
// result.then(resolve, reject) // result是一个promise实例调用then来判断当前promise的状态,
// } else {
// resolve(result) // 如果返回的不是promise,则直接改成resolve状态
// }
} catch (e) {
reject(e)
}
})
}
})
return promise
}
/*
* catch在原型上
* */
catch(onRejected) {
this.then(undefined, onRejected)
}
/*
* 返回一个promise,传人的值可能是promise,所以要判断下
* */
static resolve(value) {
return new MyPromise((resolve, reject) => {
if (value instanceof MyPromise) {
value.then(resolve, reject)
} else {
resolve(value)
}
})
}
/*返回一个promise,只处理错误的*/
static reject(reason) {
return new MyPromise((resolve, reject) => {
reject(reason)
})
}
/*
* 返回一个promise,只有所有的promise成功结果才是成功,只要有一个失败就失败
* promises:是一个数组
* */
static all(promises) {
if (!Array.isArray(promises)) {
const type = typeof promises
return new TypeError(`TypeError: ${type} ${promises} is not iterable`)
}
const values = new Array(promises.length) // 创建一个和传入参数数组长度一样的数组,用来保存promise成功的value
let resolvedCount = 0 // 保存状态为resolve的个数
return new MyPromise((resolve, reject) => {
// 遍历promises,获取每个promise的状态
promises.forEach((p, index) => {
p.then(
value => { // 执行这里的都是成功的
values[index] = value // 保存的顺序要和传入的数组参数的顺序一样
resolvedCount++
if (resolvedCount === promises.length) { // 如果有失败的那这个条件将不会成立
resolve(values)
}
},
reason => {
reject(reason) // 只要有一个失败return的promise的状态就是reject
}
)
})
})
}
static race(promises) {
return new MyPromise((resolve, reject) => {
// 遍历promises,获取每个promise的状态
promises.forEach(p => {
p.then(
value => { // 执行这里的都是成功的
resolve(value)
},
reason => {
reject(reason) // 只要有一个失败return的promise的状态就是reject
}
)
})
})
}
}
网友评论