// _Promise.js
// 先定义三个常量表示状态
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
function isFunction(fn) {
return typeof fn === 'function';
}
function isObject(ob) {
return typeof ob === 'object';
}
function isNull(value) {
return value === null;
}
function resolvePromise(promise, value, resolve, reject) {
// 自己调用自己
if (promise === value) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'));
}
// if (value instanceof _Promise) {
// value.then(resolve, reject);
// } else {
// resolve(value);
// }
if (isFunction(value) || isObject(value)) {
if (isNull(value)) {
return resolve(value);
}
let then;
try {
then = value.then;
} catch (err) {
return reject(err);
}
if (isFunction(then)) {
// then里面resolve 和 reject 只能有一个执行,因此加一个锁。
let called = false;
try {
then.call(
// this 指向value
value,
// resolve
val => {
if (called) return;
called = true;
resolvePromise(promise, val, resolve, reject);
},
// reject
val => {
if (called) return;
called = true;
reject(val);
}
);
} catch (err) {
if (called) return;
return reject(err);
}
} else {
// 如果直接是一个值,就resolve它
return resolve(value);
}
} else {
// 如果直接是一个值,就resolve它
return resolve(value);
}
}
// 新建 _Promise 类
class _Promise {
constructor(executor) {
// executor 是一个执行器,进入会立即执行
// 并传入resolve和reject方法
try {
executor(this.resolve, this.reject);
} catch (error) {
this.reject(error);
}
}
// 储存状态的变量,初始值是 pending
status = PENDING;
// 成功之后的值
value = null;
// 失败之后的原因
reason = null;
// 存储成功回调函数
onFulfilledCallbackList = [];
// 存储失败回调函数
onRejectedCallbackList = [];
// 更改成功后的状态
resolve = value => {
// 只有状态是等待,才执行状态修改
if (this.status === PENDING) {
// 状态修改为成功
this.status = FULFILLED;
// 保存成功之后的值
this.value = value;
// resolve里面将所有成功的回调拿出来执行
while (this.onFulfilledCallbackList.length) {
// Array.shift() 取出数组第一个元素,然后()调用,shift不是纯函数,取出后,数组将失去该元素,直到数组为空
this.onFulfilledCallbackList.shift()(value);
}
}
};
// 更改失败后的状态
reject = reason => {
// 只有状态是等待,才执行状态修改
if (this.status === PENDING) {
// 状态成功为失败
this.status = REJECTED;
// 保存失败后的原因
this.reason = reason;
// resolve里面将所有失败的回调拿出来执行
while (this.onRejectedCallbackList.length) {
this.onRejectedCallbackList.shift()(reason);
}
}
};
then(onFulfilled, onRejected) {
const realOnFulfilled = isFunction(onFulfilled) ? onFulfilled : value => value;
const realOnRejected = isFunction(onRejected)
? onRejected
: reason => {
throw reason;
};
// 为了链式调用这里直接创建一个 _Promise,并在后面 return 出去
const subPromise = new _Promise((resolve, reject) => {
const fulfilledMicrotask = () => {
// 创建一个微任务等待 subPromise 完成初始化
// 开始采用的queueMicrotask来模拟微任务,但是queueMicrotask是使用promise搞得,这里就有点套娃的柑橘了,所以换成了setTimeout
// queueMicrotask(() => {
// });
setTimeout(() => {
try {
// 获取成功回调函数的执行结果
const x = realOnFulfilled(this.value);
// 传入 resolvePromise 集中处理
resolvePromise(subPromise, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
};
const rejectedMicrotask = () => {
// 创建一个微任务等待 subPromise 完成初始化
setTimeout(() => {
try {
// 调用失败回调,并且把原因返回
const x = realOnRejected(this.reason);
// 传入 resolvePromise 集中处理
resolvePromise(subPromise, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
// queueMicrotask(() => {
// });
};
const statusHandleMap = {
[FULFILLED]: fulfilledMicrotask,
[REJECTED]: rejectedMicrotask,
[PENDING]: () => {
this.onFulfilledCallbackList.push(fulfilledMicrotask);
this.onRejectedCallbackList.push(rejectedMicrotask);
}
};
statusHandleMap[this.status]();
// 判断状态
// if (this.status === FULFILLED) {
// fulfilledMicrotask();
// } else if (this.status === REJECTED) {
// rejectedMicrotask();
// } else if (this.status === PENDING) {
// // 等待
// // 因为不知道后面状态的变化情况,所以将成功回调和失败回调存储起来
// // 等到执行成功失败函数的时候再传递
// this.onFulfilledCallbacks.push(fulfilledMicrotask);
// this.onRejectedCallbacks.push(rejectedMicrotask);
// }
});
return subPromise;
}
// resolve 静态方法
static resolve(parameter) {
console.log('value parameter');
// 如果传入 _Promise 就直接返回
if (parameter instanceof _Promise) {
return parameter;
}
// 转成常规方式
return new _Promise(resolve => {
resolve(parameter);
});
}
// reject 静态方法
static reject(reason) {
return new _Promise((resolve, reject) => {
reject(reason);
});
}
}
// export { _Promise };
// module.exports = _Promise;
手写promise
转载本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。

提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
promise用法总结以及手写promise
Promise.all() 接收一个 Promise 数组,返回一个新的 Promise,当所有的 Promise 都成功时,该 Promise 会成功,返回一
前端 javascript 异步操作 回调函数 数组 -
Promise从入门到手写 | [Promise系列一]
从零开始,带着你入门Promise并亲手实现。本文分为四大部分,包括Promise介绍,Promise特点,Promise使用,和Promise手写~
JavaScript 回调函数 返回结果 异步操作 -
手写Promise实现过程
手写Promise实现过程 1、实现Promise的核心功能 2、判断下当执行器
回调函数 数组 构造器 值传递 静态方法 -
java 下载xslx文件打不开
Tomcat 输入http://localhost:8080网页打不开 1 2 3 4 5分步阅读 一般情况下,我们成功安装好Tomcat后,在浏览器输入http:/
java 下载xslx文件打不开 java tomcat 服务器 解决方法