1.写promise构造器
- 就是写new Promise()的过程
(1)constructor传递两个参数reject和reslove,new Promise时立即调用
(2)resolve和reject可以被调用,所以他们两个是函数
(3)resolve和reject被调用时改变当前promise的状态(得到两个属性):promise的状态和结果(状态有pending[初始状态],fulfilled,rejected)
console.log(Promise.resolve(1))
(4)因此在调用reslove和reject时就是改变状态和结果,要注意的是promise的状态只能改变一次就不能更改了,使用在写reslove和reject函数时要先检查状态是否改变
class MyPromise{
//设置私有属性,这两个为状态和结果的初始值
#state = 'pending'
#result = undefined
constructor(executor){
//设置resolve和reject
const resolve = (value)=> {
if(this.#state !== 'pending') return
//改变状态和结果
this.#state = 'fulfilled'
this.#result = value
}
const reject = (reason)=> {
if(this.#state !== 'pending') return
this.#state = 'rejected'
this.#result = reason
}
executor()
}
}
这里优化一下写法:相近的语句写成函数+软编码
const PENDING = 'pending';
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class MyPromise{
//设置私有属性,这两个为状态和结果的初始值
#state = 'pending'
#result = undefined
#changeState = function(state,result){
//校验
if(this.#state !== PENDING) return
//改变状态和结果
this.#state = state
this.#result = result
}
constructor(executor){
//设置resolve和reject
const resolve = (value)=> {
this.#changeState(FULFILLED,value)
}
const reject = (reason)=> {
this.#changeState(REJECTED,reason)
}
executor(resolve,reject)
}
}
(5)在执行promise的时候抛出错误,状态变为rejected,结果为抛出的结果,所以executor用try catch包住,这里要注意的是在promise中只能捕获同步错误,**异步错误无法捕获
const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";
class MyPromise {
//设置私有属性,这两个为状态和结果的初始值
#state = "pending";
#result = undefined;
#changeState = function (state, result) {
//校验
if (this.#state !== PENDING) return;
//改变状态和结果
this.#state = state;
this.#result = result;
};
constructor(executor) {
//设置resolve和reject
const resolve = (value) => {
this.#changeState(FULFILLED, value);
};
const reject = (reason) => {
this.#changeState(REJECTED, reason);
};
try {
executor(resolve, reject);
} catch (error) {
//掉reject把状态变为rejected
reject(error);
}
}
}
2.then
我们知道promise的then方法接收两个回调,返回一个promise
这时候有两个问题
- 一.then什么时候执行成功的方法
onFulfilled,什么时候执行失败的方法onRejected - 二.then调用返回的promise什么时候为成功
resolve,什么时候失败reject
一 解决onFulfilled和onRejected调用问题
1.当前的promise为完成状态时调用onFulfilled,状态为拒绝就调用onRejected
2.promise为pending状态也要解决(比如放在setTimeout中),而then方法中不知道是不是等待状态,可以看到#changeState中可以判断状态,但是#changeState中拿不到onFulfilled等这四个东西
then方法操作步骤
- 把这4个包成对象放进数组(用数组装是因为可能多次调用then有多个)
then和changeState中调用一个方法run- 如果promise处于等待
pending的状态,等状态改变了,(等待->fullfilled/rejected)就调用run开始执行
run方法:
- 如果是
pending就return - 如果状态是
fulfilled和rejected就执行onFulfilled和onRejected,执行前记得判断传入的是不是函数
const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";
class MyPromise {
//设置私有属性,这两个为状态和结果的初始值
#state = "pending";
#result = undefined;
#handlers = []; //装fulFilled,rejected,resolve,reject的数组
//改变状态
#changeState = function (state, result) {
//校验
if (this.#state !== PENDING) return;
//改变状态和结果
this.#state = state;
this.#result = result;
//调用run
this.#run();
};
//执行那四个
#run = function () {
if (this.#state == PENDING) return;
//如果数组不为空就执行
while (this.#handlers.length) {
//一个个拿出来执行,用shift删除并返回的一个元素
const { onFulfilled, onRejected, resolve, reject } =
this.#handlers.shift();
if (this.#state === FULFILLED) {
if (typeof onFulfilled === "function") {
onFulfilled(this.#result);
}
} else {
if (typeof onRejected === "function") {
onRejected(this.#result);
}
}
}
};
constructor(executor) {
//设置resolve和reject
const resolve = (value) => {
this.#changeState(FULFILLED, value);
};
const reject = (reason) => {
this.#changeState(REJECTED, reason);
};
try {
executor(resolve, reject);
} catch (error) {
//掉reject把状态变为rejected
reject(error);
}
}
then(onFulfilled, onRejected) {
return new MyPromise((resolve, reject) => {
//1.放进数组
this.#handlers.push({
onFulfilled,
onRejected,
resolve,
reject,
});
//2.调用run
this.#run();
});
}
}
到此onFulfilled和onRejected什么时候执行已经完成
二 解决返回的promise什么时候完成,什么时候失败
- 当对应的回调传入的不是函数时,进行穿透,promise原来为什么状态现在就为什么状态
if (this.#state === FULFILLED) {
if (typeof onFulfilled === "function") {
onFulfilled(this.#result);
} else {
resolve(this.#result);
}
} else {
if (typeof onRejected === "function") {
onRejected(this.#result);
} else {
reject(this.#state);
}
}
- 返回的是函数
if (typeof onFulfilled === "function") {
try {
const data = this.onFulfilled(this.#result)
resolve(data)
} catch (error) {
reject(error)
}
} else {
resolve(this.#result);
}
优化一下代码
const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";
class MyPromise {
//设置私有属性,这两个为状态和结果的初始值
#state = "pending";
#result = undefined;
#handlers = []; //装fulFilled,rejected,resolve,reject的数组
//改变状态
#changeState = function (state, result) {
//校验
if (this.#state !== PENDING) return;
//改变状态和结果
this.#state = state;
this.#result = result;
//调用run
this.#run();
};
//提出公共代码
#runOne = function (callback, resolve, reject) {
if (typeof callback !== "function") {
const settled = this.#state === FULFILLED ? resolve : reject;
settled(this.#result);
return;
}
try {
//成功
const data = callback(this.#result);
resolve(data);
} catch (error) {
//失败
reject(error);
}
};
//执行那四个
#run = function () {
if (this.#state == PENDING) return;
//如果数组不为空就执行
while (this.#handlers.length) {
//一个个拿出来执行,用shift删除并返回的一个元素
const { onFulfilled, onRejected, resolve, reject } =
this.#handlers.shift();
if (this.#state === FULFILLED) {
this.#runOne(onFulfilled, resolve, reject);
} else {
this.#runOne(onRejected, resolve, reject);
}
}
};
//构造器
constructor(executor) {
//设置resolve和reject
const resolve = (value) => {
this.#changeState(FULFILLED, value);
};
const reject = (reason) => {
this.#changeState(REJECTED, reason);
};
try {
executor(resolve, reject);
} catch (error) {
//掉reject把状态变为rejected
reject(error);
}
}
then(onFulfilled, onRejected) {
return new MyPromise((resolve, reject) => {
//1.放进数组
this.#handlers.push({
onFulfilled,
onRejected,
resolve,
reject,
});
//2.调用run
this.#run();
});
}
}
- 调用函数的返回结果是一个promise
这里要先写一个判断是不是promise的函数(一个东西只要有属性then并且then是一个函数,那么就是promise)
#isPromise = function(value){
if(value !== null && (typeof value === 'object' || typeof value === 'function')){
return typeof value.then === 'function'
}
return false
}
const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";
class MyPromise {
//设置私有属性,这两个为状态和结果的初始值
#state = "pending";
#result = undefined;
#handlers = []; //装fulFilled,rejected,resolve,reject的数组
//改变状态
#changeState = function (state, result) {
//校验
if (this.#state !== PENDING) return;
//改变状态和结果
this.#state = state;
this.#result = result;
//调用run
this.#run();
};
//判断是不是promise
#isPromise = function(value){
if(value !== null && (typeof value === 'object' || typeof value === 'function')){
return typeof value.then === 'function'
}
return false
}
//放进微队列
#runMicroTask = function(fun){
//node环境
if(typeof process === 'object' && typeof process.nextTick === 'function'){
process.nextTick(fun)
}else if(typeof MutationObserver === 'function'){
const ob = new MutationObserver(fun)
const textNode = document.createTextNode('1')
ob.observe(textNode,{
characterData:true
})
textNode.data = '2'
}else{
setTimeout(fun,0)
}
}
//提出公共代码
#runOne = function (callback, resolve, reject) {
if (typeof callback !== "function") {
const settled = this.#state === FULFILLED ? resolve : reject;
settled(this.#result);
return;
}
try {
//成功
const data = callback(this.#result);
//判断传入函数的返回结果是不是promise
if(this.#isPromise(data)){
//是promise就调then,promise是完成就调resolve,失败就调reject
data.then(resolve,reject)
}else{
resolve(data)
}
resolve(data);
} catch (error) {
//失败
reject(error);
}
};
//执行那四个
#run = function () {
if (this.#state == PENDING) return;
//如果数组不为空就执行
while (this.#handlers.length) {
//一个个拿出来执行,用shift删除并返回的一个元素
const { onFulfilled, onRejected, resolve, reject } =
this.#handlers.shift();
if (this.#state === FULFILLED) {
this.#runOne(onFulfilled, resolve, reject);
} else {
this.#runOne(onRejected, resolve, reject);
}
}
};
//构造器
constructor(executor) {
//设置resolve和reject
const resolve = (value) => {
this.#changeState(FULFILLED, value);
};
const reject = (reason) => {
this.#changeState(REJECTED, reason);
};
try {
executor(resolve, reject);
} catch (error) {
//掉reject把状态变为rejected
reject(error);
}
}
then(onFulfilled, onRejected) {
return new MyPromise((resolve, reject) => {
//1.放进数组
this.#handlers.push({
onFulfilled,
onRejected,
resolve,
reject,
});
//2.调用run
this.#run();
});
}
}
三 其他操作
const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";
class MyPromise {
//设置私有属性,这两个为状态和结果的初始值
#state = "pending";
#result = undefined;
#handlers = []; //装fulFilled,rejected,resolve,reject的数组
//改变状态
#changeState = function (state, result) {
//校验
if (this.#state !== PENDING) return;
//改变状态和结果
this.#state = state;
this.#result = result;
//调用run
this.#run();
};
//判断是不是promise
#isPromise = function(value){
if(value !== null && (typeof value === 'object' || typeof value === 'function')){
return typeof value.then === 'function'
}
return false
}
//放进微队列
#runMicroTask = function(fun){
//node环境
if(typeof process === 'object' && typeof process.nextTick === 'function'){
process.nextTick(fun)
}else if(typeof MutationObserver === 'function'){
const ob = new MutationObserver(fun)
const textNode = document.createTextNode('1')
ob.observe(textNode,{
characterData:true
})
textNode.data = '2'
}else{
setTimeout(fun,0)
}
}
//提出公共代码
#runOne = function (callback, resolve, reject) {
if (typeof callback !== "function") {
const settled = this.#state === FULFILLED ? resolve : reject;
settled(this.#result);
return;
}
try {
//成功
const data = callback(this.#result);
//判断传入函数的返回结果是不是promise
if(this.#isPromise(data)){
//是promise就调then,promise是完成就调resolve,失败就调reject
data.then(resolve,reject)
}else{
resolve(data)
}
resolve(data);
} catch (error) {
//失败
reject(error);
}
};
//执行那四个
#run = function () {
if (this.#state == PENDING) return;
//如果数组不为空就执行
while (this.#handlers.length) {
//一个个拿出来执行,用shift删除并返回的一个元素
const { onFulfilled, onRejected, resolve, reject } =
this.#handlers.shift();
if (this.#state === FULFILLED) {
this.#runOne(onFulfilled, resolve, reject);
} else {
this.#runOne(onRejected, resolve, reject);
}
}
};
//构造器
constructor(executor) {
//设置resolve和reject
const resolve = (value) => {
this.#changeState(FULFILLED, value);
};
const reject = (reason) => {
this.#changeState(REJECTED, reason);
};
try {
executor(resolve, reject);
} catch (error) {
//掉reject把状态变为rejected
reject(error);
}
}
then(onFulfilled, onRejected) {
return new MyPromise((resolve, reject) => {
//1.放进数组
this.#handlers.push({
onFulfilled,
onRejected,
resolve,
reject,
});
//2.调用run
this.#run();
});
}
//处理错误的回调
catch(onRejected){
//直接调then,给成功部分传undefined
return this.then(undefined,onRejected)
}
//不论成功失败都要执行
//也返回一个promise,跟当前promise状态一至
finally(onFinally){
return this.then((data)=>{
onFinally()
return
},(err)=>{
onFinally()
throw err
})
}
//如果参数是promise就直接返回promise,
//如果是一个A+规范的,即有一个then方法的对象或函数就调用then方法
static resolve(value){
if(value instanceof MyPromise) return value
//因为静态方法中不能调用实例方法,所以把resolve和reject提出来
let _resolve,_reject
const p = new MyPromise((resolve,reject)=>{
_resolve = resolve
_reject = reject
})
if(p.#isPromise(value)){
value.then(_resolve,_reject)
}else{
_resolve(value)
}
return p
}
//不管传什么都返回一个promise,promise里直接拒绝
static reject(value){
return new MyPromise((resolve,reject)=>{
reject(value)
})
}
//promise的all方法
static all(value){
let res,rej
//返回的是一个promise
const p = new MyPromise((resolve,reject)=>{
res = resolve
rej = reject
})
//设置p的状态
//1.如果传的是个空数组返回成功的空数组
//2.不为空就遍历全部
let count = 0//记录数组中有几个元素
const result = []//存储结果
let finish = 0//完成的数量
for(let item of value){
let i = count
count++
MyPromise.resolve(item)//保证每项都是promise
.then(data=>{
//成功的数据放到result中
result[i] = data
//判断是否全部遍历
finish++
if(finish === count){
res(result)
}
},rej)//一个失败会导致全部失败,所以失败直接传rej
}
if(count === 0){
return this.resolve(result)
}
return p
}
}