- 创建promise的基础框架
function MyPromise(executor) {
function resolve(value) {
}
function reject(reason) {
}
try {
// executor为new promise时传入的函数,executor的两个参数分别为成功回调函数和失败的回调
executor(resolve, reject)
} catch (reason) {
reject(reason)
}
}
使用:
let promise = new MyPromise(function(resolve, reject) {
resolve(123);
})
- 添加状态机
promise是一个状态机,只要promise执行就进入pending状态,然后是成功状态的话就是fulfilled,失败状态的就是rejected。也就是pending -> fulfilled 或 pending -> rejected,并且状态是不可逆的,一旦转变就不会再变了
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
function MyPromise(executor) {
let self = this;
self.state = PENDING;
function resolve(value) {
if (self.state === PENDING) {
self.state = FULFILLED;
}
}
function reject(reason) {
if (self.state === PENDING) {
self.state = REJECTED;
}
}
try {
executor(resolve, reject);
} catch (reason) {
reject(reason);
}
}
- 添加状态后还没有结束,发现promise都有then方法,那么我们来添加一下
// 添加then方法后,我们的构造函数也需要改造一下
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
function MyPromise(executor) {
let self = this;
// 状态机初始状态
self.state = PENDING
// promise成功后吐出的数据
self.value = null
// promise失败后吐出的数据
self.reason = null
function resolve(value) {
if (self.state === PENDING) {
self.state = FULFILLED
self.value = value
}
}
function reject(reason) {
if (self.state === PENDING) {
self.state = REJECTED
self.reason = reason
}
}
try {
executor(resolve, reject)
} catch (reason) {
reject(reason)
}
}
// 添加then方法,因为我们调用then是直接使用类来调用,并不是实例,所以直接定义在原型上
MyPromise.prototype.then = function(onFuifilled, onRejected) {
let self = this
if (self.state === FULFILLED) {
onFuifilled(self.value)
}
if (self.state === REJECTED) {
onRejected(self.reason)
}
}
我们都知道then方法有两个参数, 分别是成功的回调和失败回调,对应上面就是onFulfilled,onRejected
使用一下:
let promise = new MyPromise(function(resolve, reject) {
resolve(1111)
})
promise.then(res => {
console.log(res)
})
我们发现,同步函数这么执行时没有问题,但是我们添加了异步函数比如说setTimeout后就不正常了,比如我们像这样执行
let MyPromise1 = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve(1111)
})})
MyPromise1.then((res) => {
console.log(res)
})
1.目前的代码在调用then()方法时,state仍是pending状态,当timer到时候调用resolve()把state修改为fulfilled状态,但是onFulfilled()函数已经没有时机调用了;
2.也就是代码先执行了then方法,然后才去执行的构造函数中的reslove方法
- 实现异步调用resolve
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejectd'
function MyPromise (executor) {
let self = this
self.state = PENDING
self.value = null
self.reason = null
// 添加这两个数组来存放未来要执行的方法
self.onFulfilledCallBacks = []
self.onRejectedCallBacks = []
function resolve (value) {
if (self.state === PENDING) {
self.state = FULFILLED
self.value = value
self.onFulfilledCallBacks.forEach(fn => {
fn()
})
}
}
function reject (reason) {
if (self.state === PENDING) {
self.state = REJECTED
self.reason = reason
self.onRejectedCallBacks.forEach(fn => {
fn()
})
}
}
try {
executor(resolve, reject)
} catch {
reject(reason)
}
}
MyPromise.prototype.then = function (onFulfilled, onRejected) {
let self = this
// 通过以上例子,我们知道异步先执行的then,并且这时state是PENDING,将未来要执行的方法放在对应的数组中
// 然后执行完then后,已经存放未来要执行的方法,然后再执行reslove方法时只需要一个个拿出来去执行即可
if (self.state === PENDING) {
self.onFulfilledCallBacks.push(() => {
onFulfilled(self.value)
})
self.onRejectedCallBacks.push(() => {
onRejected(self.reason)
})
}
if (self.state === FULFILLED) {
onFulfilled(self.value)
}
if (self.state === REJECTED) {
onRejected(self.reason)
}
}
使用:
let MyPromise1 = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve(2222)
})
})
MyPromise1.then((res) => {
console.log(res)
})
以上简单完成了promise,还有很多没有实现,后续再来跟大家分享