JS中常用的处理异步的方式就是回调和发布订阅。promise也是发布订阅模式的一种实现。then方法注册事件,执行器executor中的异步任务触发发布消息改变状态并执行注册事件队列里方法,也就是发布订阅模式里面的注册事件,发布通知,执行订阅的事件
实现promise要按照Promise的规范,一个基本的promise包括
具体实现如下:
// 三个状态
const PENDING = "pending";
const REJECTED = "rejected";
const FULFILLED = "fulfilled";
// 一个构造(包含一个执行器executor),
function PromiseTest(executor){}
// 一个then方法(入参为成功回调和失败回调)返回时一个promise
PromiseTest.prototype.then = function (onFulfilled, onRejected) {}
// 初始化构造方法
function PromiseTest(executor){
let _this = this;
// 初始化状态和成功和失败
_this.status = PENDING;
_this.value = null;
_this.reason = null;
// 初始化成功回调和失败回调的数组
_this.onFulfilledCallbacks = [];
_this.onRejectedCallbacks = [];
function resolve(value){
// 防止执行器中是同步代码时造成then立即执行
setTimeout(() => {
_this.status = FULFILLED;
_this.value = value;
_this.onFulfilledCallbacks.forEach(fn => fn(value))
}, 0);
}
function reject(reason){
// 防止执行器中是同步代码时造成then立即执行
setTimeout(() => {
_this.status = REJECTED;
_this.reason = reason;
_this.onRejectedCallbacks.forEach(fn => fn(reason))
}, 0);
}
try {
executor(resolve, reject)
} catch (error) {
reject(error)
}
}
PromiseTest.prototype.then = function(onFulfilled, onRejected) {
let _this = this;
// 确保入参是函数
typeof onFulfilled === 'function' ? onFulfilled : value => value
typeof onRejected === 'function' ? onRejected : reason => {throw new Error(reason)}
return new PromiseTest(function(resolve, reject) {
if (_this.status === FULFILLED) {
let result = onFulfilled(_this.value)
result instanceof PromiseTest ? result.then(resolve, reject) : resolve(result)
}
if (_this.status === REJECTED) {
let result = onRejected(_this.reason)
result instanceof PromiseTest ? result.then(resolve, reject) : reject(result)
}
if (_this.status === PENDING) {
_this.onFulfilledCallbacks.push(()=> {
let result = onFulfilled(_this.value)
result instanceof PromiseTest ? result.then(resolve, reject) : resolve(result)
})
_this.onRejectedCallbacks.push(()=> {
let result = onFulfilled(_this.value)
result instanceof PromiseTest ? result.then(resolve, reject) : resolve(result)
})
}
})
}
const p = new PromiseTest((resolve, reject)=>{
// resolve(123)
new PromiseTest((resolve, reject)=>{
setTimeout(() => {
resolve(123)
}, 2000);
}).then(res => {
resolve(res)
})
// setTimeout(() => {
// resolve(123)
// }, 2000);
})
p.then((res)=>{
console.log(res, 'res1')
return new PromiseTest((resolve, reject)=>{
setTimeout(() => {
resolve(res + 'next')
}, 2000);
})
}).then(res=>{
console.log(res, 'res2')
})
console.log(111)
上述实现一个基本的promise,在规范中还要在then方法中实现各种promise库的兼容,需要在then方法内抽离出一个函数resolvePromise来判断onFulfilled(_this.value)返回的是符合pormise标准的对象还是普通值,如果是符合pormise标准的对象继续递归判断。。。实现基础的promise就不写这些了,毕竟也没人会自己写个promise拿来用吧