promise源码
/** @Author: your name* @Date: 2022-02-27 23:46:11* @LastEditTime: 2022-02-28 21:37:51* @LastEditors: Please set LastEditors* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1F
·
/*
* @Author: your name
* @Date: 2022-02-27 23:46:11
* @LastEditTime: 2022-02-28 21:37:51
* @LastEditors: Please set LastEditors
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
* @FilePath: /demo1/promise.js
*/
// promise 原理代码
const PENDING = 'pending'; // 等待
const FULFILLED = 'fulfilled'; // 成功
const REJECTED = 'rejected'; // 失败
class MyPromise {
constructor(executor) { // 接收执行器
try {
executor(this.resolve, this.reject)
} catch (e) {
this.reject(e);
}
}
status = PENDING; // promise的状态
value = undefined; // 成功之后的值
reason = undefined; // 失败之后的值
successCallback = []; // 成功回调
failCallback = []; // 失败回调
// resolve和reject为什么要用箭头函数?
// 如果直接调用的话,普通函数this指向的是window或者undefined
// 用箭头函数就可以让this指向当前实例对象
resolve = value => {
// 如果状态不是等待 组织程序向下执行
if (this.status !== PENDING) return
// 将状态更改为成功
this.status = FULFILLED;
// 保存成功之后的值
this.value = value;
// 判断成功回调是否存在 如果存在 调用
//this.successCallback && this.successCallback(this.value) //shift 取出数组的第一位,并且会改遍原数组
while (this.successCallback.length) this.successCallback.shift()()
}
reject = reason => {
// 如果状态不是等待 组织程序向下执行
if (this.status !== PENDING) return
// 将状态更改为失败
this.status = REJECTED;
// 保存失败后的原因
this.reason = reason;
// 判断失败回调是否存在 如果存在 调用
// this.failCallback && this.failCallback(this.reason)
while (this.failCallback.length) this.failCallback.shift()();
}
then(successCallback, failCallback) {
successCallback = successCallback ? successCallback : value => value;
failCallback = failCallback ? failCallback : reason => {
throw reason
}; // then链式调用参数变为可选参数 例:promise.then().then().then((value)=>{console.log(value)}) // value
let promise2 = new MyPromise((resolve, reject) => {
// 传递一个执行器 立马执行
// 判断状态 成功
if (this.status === FULFILLED) {
setTimeout(() => { // 将下面的代码变成异步代码
try {
let x = successCallback(this.value)
// 判断 x 的值是普通值还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promise对象返回的结果
// 再根据promise对象返回的结果 界定调用resolve 还是reject
resolvePromise(x, resolve, reject);
} catch (e) { // 处理异常状态
reject(e)
}
}, 0)
} else if (this.status === REJECTED) {
setTimeout(() => { // 将下面的代码变成异步代码
try {
let x = failCallback(this.reason)
resolvePromise(x, resolve, reject);
} catch (e) { // 处理异常状态
reject(e)
}
}, 0)
} else {
// 当前状态是等待
// 将成功回调和失败回调存储起来 - 多个then方法调用
this.successCallback.push(() => {
setTimeout(() => { // 将下面的代码变成异步代码
try {
let x = successCallback(this.value);
resolvePromise(x, resolve, reject);
} catch (e) { // 处理异常状态
reject(e)
}
}, 0)
});
this.failCallback.push(() => {
setTimeout(() => { // 将下面的代码变成异步代码
try {
let x = failCallback(this.reason);
resolvePromise(x, resolve, reject);
} catch (e) { // 处理异常状态
reject(e)
}
}, 0)
});
}
});
return promise2;
}
finally(callback) {
/**
- 无论当前最终状态是成功还是失败,finally都会执行
- 我们可以在finally方法之后调用then方法拿到结果
- 这个函数是在原型对象上用的
* **/
return this.then(value => {
return MyPromise.resolve(callback()).then(() => value)
}, reason => {
return MyPromise.resolve(callback()).then(() => {
throw reason
})
})
}
catch(failCallback) {
/**
- catch方法是为了捕获promise对象的所有错误回调的
- 直接调用then方法,然后成功的地方传递undefined,错误的地方传递reason
- catch方法是作用在原型对象上的方法
* **/
return this.then(undefined, failCallback);
}
static all(array) {
/**
* 分析一下:
- all方法接收一个数组,数组中可以是普通值也可以是promise对象
- 数组中值得顺序一定是我们得到的结果的顺序
- promise返回值也是一个promise对象,可以调用then方法
- 如果数组中所有值是成功的,那么then里面就是成功回调,如果有一个值是失败的,那么then里面就是失败的
- 使用all方法是用类直接调用,那么all一定是一个静态方法
**/
let result = [];
let index = 0;
return new MyPromise((resolve, reject) => {
function addData(key, value) {
// 保存每个传入参数执行完毕,并存储返回值
result[key] = value;
index++;
if (index === array.length) {
resolve(result)
}
}
for (let i = 0; i < array.length; i++) {
let current = array[i];
if (current instanceof MyPromise) {
// promise对象
current.then(value => addData(i, value), reason => reject(reason))
} else {
// 普通值
addData(i, array[i])
}
}
})
}
static resolve(value) {
/**
resolve方法的作用是将给定的值转换为promise对象 resolve的返回值的promise对象
如果参数就是一个promise对象,直接返回,如果是一个值,那么需要生成一个promise对象,把值进行返回
是Promise类的一个静态方法
* **/
if (value instanceof MyPromise) return value;
return new MyPromise(resolve => resolve(value))
}
}
function resolvePromise(x, resolve, reject) {
if (x instanceof MyPromise) {
// promise 对象
// x.then( value => resolve(value),reason => reject(reason))
x.then(resolve, reject) // 简化
} else {
// 普通值
resolve(x)
}
}
module.exports = MyPromise;
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
已为社区贡献1条内容
所有评论(0)