实现一个Promise
程序员文章站
2022-07-03 09:33:08
...
1.极简版Promise
在Promise的用法中,我们使用如下方式来使用Promise
,那么这个最简单的功能是如何实现的呢,下面我们来探索一下
let p = new Promise((resolve, reject) => {
resolve('test');
});
p.then(data=> {
console.log(data); // test
})
-
Promise
是一个类 - 有三个状态:
pending
、fulfilled
、rejected
- 接收一个函数作为参数,这个函数在内部被执行
- 这个函数有两个参数
resolve
,reject
,resolve
和reject
都是函数,可以把值传入then
方法 -
Promise
实例上有一个then
方法,这个then
方法返回一个Promise
- 如果是
resolve
,返回resolve
的值 - 如果是
reject
,返回reject
的原因
下面我们使用代码实现上面的内容,新建promise.js文件,在文件中输入以下代码
// 2. 有三个状态:`pending`、`fulfilled`、`rejected`
const PENDING = 'PENDING';
const FULFILLED = "FULFILLED";
const REJECTED = "REJECTED";
// 1. `Promise`是一个类
class Promise {
constructor(executor) {
this.value = undefined;
this.reject = undefined;
this.status = PENDING;
// 4. 这个函数有两个参数`resolve`, `reject`
let resolve = value => {
if(this.status === PENDING) {
this.value = value;
this.status = FULFILLED;
}
}
let reject = reason => {
if(this.status === PENDING) {
this.reason = reason;
this.status = REJECTED;
}
}
// 3. 接收一个函数作为参数,这个函数在内部被执行
executor(resolve, reject);
}
// 5. `Promise`实例上有一个`then`方法
then(onFulfilled, onRejected) {
// 5. 这个`then`方法返回一个`Promise`
let promiseThen = new Promise((resolve, reject) => {
// 6. 如果是`resolve`,返回`resolve`的值
if(this.status === FULFILLED) {
let x = onFulfilled(this.value);
resolve(x);
}
// 7. 如果是`reject`,返回`reject`的原因
if(this.status === REJECTED) {
let x = onRejected(this.reason);
reject(x);
}
})
return promiseThen;
}
}
2.处理pending
状态
如果我们使用如下方式使用Promise
,因为加了定时器,这个时候的传入then
中的状态是pending
,所以在then
方法中就获取不到值了。所以在这里要加上对于then
方法中pending
状态的处理方法
let p = new Promise((resolve, reject) => {
setTimeout(function() {
resolve('一个有延迟的resolve');
},1000)
});
p.then((data, reason) => {
console.log(data)
})
我们使用回调函数来处理这种场景,在then
方法中,如果发现状态是pending
,将处理方法放入一个函数中,在resolve和reject中调用这些方法。接着上面的7步补充如下:
- 如果是
reject
,收集处理方法 - 在
resolve
和reject
中调用这些方法
promise.js
的代码改动如下
// 2. 有三个状态:`pending`、`fulfilled`、`rejected`
const PENDING = 'PENDING';
const FULFILLED = "FULFILLED";
const REJECTED = "REJECTED";
// 1. `Promise`是一个类
class Promise {
constructor(executor) {
this.value = undefined;
this.reject = undefined;
this.status = PENDING;
// resolve和reject的函数组成数组
this.onResolvedCallbacks = [];
this.onRejectedCallbacks = [];
// 4. 这个函数有两个参数`resolve`, `reject`
let resolve = value => {
if(this.status === PENDING) {
this.value = value;
this.status = FULFILLED;
// 9. 在`resolve`和`reject`中调用这些方法
this.onResolvedCallbacks.forEach(fn=>fn());
}
}
let reject = reason => {
if(this.status === PENDING) {
this.reason = reason;
this.status = REJECTED;
// 9. 在`resolve`和`reject`中调用这些方法
this.onRejectedCallbacks.forEach(fn=>fn());
}
}
// 3. 接收一个函数作为参数,这个函数在内部被执行
executor(resolve, reject);
}
// 5. `Promise`实例上有一个`then`方法
then(onFulfilled, onRejected) {
// 5. 这个`then`方法返回一个`Promise`
let promiseThen = new Promise((resolve, reject) => {
// 6. 如果是`resolve`,返回`resolve`的值
if(this.status === FULFILLED) {
let x = onFulfilled(this.value);
resolve(x);
}
// 7. 如果是`reject`,返回`reject`的原因
if(this.status === REJECTED) {
let x = onRejected(this.reason);
reject(x);
}
// 8. 如果是`pending`,收集处理方法
if(this.status === PENDING) {
let x = onFulfilled(this.value);
this.onResolvedCallbacks.push(() => {
let x = onFulfilled(this.value);
resolve(x);
})
this.onRejectedCallbacks.push(() => {
let x= onRejected(this.reason);
reject(x);
})
}
})
return promiseThen;
}
}
3.then方法中的Promise
我们知道,then
方法返回了一个Promise
,这个Promise
只能处理简单值,如果传入的还是Promise
,就歇菜了,所以还要对这个Promise传入的参数进行处理。接着上面的9步继续。
- 传入普通值,直接resolve
- 传入promise,处理promise
在代码中加入resolvePromise
函数
const resolvePromise = (promiseThen, x, resolve, reject) => {
// 11. 传入promise,处理promise
if((typeof x === 'object' && x !== null) || typeof x === 'function') {
let then = x.then;
if(typeof then === 'function') {
then.call(x, y => {
resolvePromise(promiseThen,y,resolve,reject)
}, r => {
reject(r);
})
} else {
// 10. 传入普通值,直接resolve
resolve(x);
}
}
}
目前为止,我们实现了一个简单的Promise,完整代码如下。
// 2. 有三个状态:`pending`、`fulfilled`、`rejected`
const PENDING = 'PENDING';
const FULFILLED = "FULFILLED";
const REJECTED = "REJECTED";
const resolvePromise = (promiseThen, x, resolve, reject) => {
// 11. 传入promise,处理promise
if((typeof x === 'object' && x !== null) || typeof x === 'function') {
let then = x.then;
if(typeof then === 'function') {
then.call(x, y => {
resolvePromise(promiseThen,y,resolve,reject)
}, r => {
reject(r);
})
} else {
// 10. 传入普通值,直接resolve
resolve(x);
}
}
}
// 1. `Promise`是一个类
class Promise {
constructor(executor) {
this.value = undefined;
this.reject = undefined;
this.status = PENDING;
// resolve和reject的函数组成数组
this.onResolvedCallbacks = [];
this.onRejectedCallbacks = [];
// 4. 这个函数有两个参数`resolve`, `reject`
let resolve = value => {
if(this.status === PENDING) {
this.value = value;
this.status = FULFILLED;
// 9. 在`resolve`和`reject`中调用这些方法
this.onResolvedCallbacks.forEach(fn=>fn());
}
}
let reject = reason => {
if(this.status === PENDING) {
this.reason = reason;
this.status = REJECTED;
// 9. 在`resolve`和`reject`中调用这些方法
this.onRejectedCallbacks.forEach(fn=>fn());
}
}
// 3. 接收一个函数作为参数,这个函数在内部被执行
executor(resolve, reject);
}
// 5. `Promise`实例上有一个`then`方法
then(onFulfilled, onRejected) {
// 5. 这个`then`方法返回一个`Promise`
let promiseThen = new Promise((resolve, reject) => {
// 6. 如果是`resolve`,返回`resolve`的值
if(this.status === FULFILLED) {
setTimeout(() => {
let x = onFulfilled(this.value);
resolvePromise(promiseThen, x, resolve, reject);
}, 0)
}
// 7. 如果是`reject`,返回`reject`的原因
if(this.status === REJECTED) {
setTimeout(() => {
let x = onRejected(this.reason);
resolvePromise(promiseThen, x, resolve, reject);
})
}
// 8. 如果是`pending`,收集处理方法
if(this.status === PENDING) {
let x = onFulfilled(this.value);
this.onResolvedCallbacks.push(() => {
setTimeout(() => {
let x = onFulfilled(this.value);
resolvePromise(promiseThen, x, resolve, reject);
})
})
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
let x= onRejected(this.reason);
resolvePromise(promiseThen, x, resolve, reject);
})
})
}
})
return promiseThen;
}
}