promise 规范原理及实现
三个状态
- pending 准备
- fulfilled 成功
- rejected 失败
两个过程
(不可逆)
- pending -> fulfilled
- pending -> rejected
一个方法
- then 其他的 都是 then 派生的方法
Promise 数据结构
{
[[PromiseState]]: "fulfilled", // 内部状态
[[PromiseResult]]: 1 // 内部变量
}
Promise Demo 运行说明
const p = new Promise(function (resolve, reject) {
console.log(0);
setTimeout(() => {
const number = parseInt(Math.random() * 100);
const isOdd = number % 2;
if (isOdd) {
resolve(number);
} else {
reject(0);
}
}, 2000);
});
console.log(1);
p.then((data) => {
console.log(2);
}).catch((err) => {
console.log(3);
});
console.log(4);
- new Promise 属于同步执行
- setTimeout 会开启异步线程
- 顺序 0 1 4 2
- Promise 的参数是一个函数,该函数同步执行
Promise 的参数 函数的参数, resolve reject 也是函数
resolve 作用
- promise 定义中调用,传入成功结果
- 改变 PromiseState 的状态为 fulfilled
- 设置 PromiseResult 值
reject 作用
- promise 定义中调用,传入失败原因
- 改变 PromiseState 的状态为 rejected
- 设置 PromiseResult 值
then 方法
- 将监听函数加入队列
- 返回一个新的 promise
promise 本质
生产者消费之模式,new promise 和 then 中生产回调提供消费,then catch finally; 达到链式调用方式改善回调地狱的目的
简单实现
const PROMISE_STATE_ENUM = {
PEDDING: "pendding",
FULFILLED: "fulfilled", // 成功
REJECTED: "rejected", // 失败
};
class MyPromise {
callbacks = []; // 队列?数组?消费后出队? 还是应为 promise.All
constructor(fn) {
this.state = PROMISE_STATE_ENUM.PEDDING;
this.result = void 0;
// console.log("同步执行");
fn(
function resolve(data) {
if (this.state === PROMISE_STATE_ENUM.PEDDING) {
this.state = PROMISE_STATE_ENUM.FULFILLED;
this.result = data;
this.callbacks.map((fn) => {
fn(this.result);
});
}
}.bind(this),
function reject() {
this.state = PROMISE_STATE_ENUM.REJECTED;
return this;
}.bind(this)
);
}
then(onFulfilled, onRejected) {
const self = this;
let promise2;
if (this.state === PROMISE_STATE_ENUM.PEDDING) {
promise2 = new MyPromise(function (resolve, reject) {
self.callbacks.push(() => {
// setTimeout(function () {
let x = onFulfilled(self.result);
resolve(x);
// });
});
});
}
if (this.state === PROMISE_STATE_ENUM.FULFILLED) {
console.log("getdata");
onFulfilled(this.result);
}
if (this.state === PROMISE_STATE_ENUM.REJECTED) {
onRejected(this.result);
}
return promise2;
}
catch(onRejected) {
this.then(null, onRejected)
}
finally() {}
static all() {}
static race() {}
static allSettled() {}
static any() {}
static resolve(a) {
return a;
}
static reject() {}
}
const p = new MyPromise(function (resolve, reject) {
setTimeout(() => {
if (1) {
resolve("should data 123");
} else {
reject("error");
}
}, 300);
});
// console.dir(MyPromise);
// console.log(p, "p");
const p1 = p.then(
(resolve) => {
// console.log(resolve, ": then 1");
return 555
},
(error) => {
console.log(error);
}
);
// console.log(p1, "p1");
p1.then((data) => {
// console.log(data, ": then 2");
});
// console.log(p, "p2");
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。