1.在 new Promise的时候接受一个方法,方法中有resolve和reject两个方法,分别对应promise状态改变时的操作
2.promise对象内部存在三种状态,分别是 pending, fulfilled, rejected,promise
3.对象在创建的时候,会立即执行其中传入的方法,并且通过resolve和reject方法改变status
4.当 promise.then执行的时候,会传入onFulfilled和onRejected方法,这时候会检查promise内部状态,这里存在三种情况:
一个是pending的时候,说明状态没有改变有可能是resolve方法被异步加载,那么会被把传入的onFulfilled和onRejected方法push到resolveCallbacks和rejectCallbacks队列当中;
第二种是fulfilled状态,说明被resolve了,那么就会执行当前的onFulfilled方法
第三种就是rejected状态,说明被reject了,那么就会执行当前的onRejected方法
5.如果resolve或者reject被异步了,那么就会先通过then将传入的方法放到callbacks队列中,等到promise内部resolve或者reject方法执行时,清空callbacks上的方法
6.promise返回的是一个promise对象,promise对象.then返回的仍然是一个promise对象
```js
/**
* promise 状态:
* pendding: 初始状态 pendding 可以转为 fulfilled和 rejected
* fulfilled
* rejected
*/
class Commitment {
static PENDING = "待定";
static FULFILLED = "成功";
static REJECTED = "拒绝";
constructor(func) {
this.status = Commitment.PENDING; // 一开始为 pendding
this.result = null; // 结果
this.resolveCallbacks = [];
this.rejectCallbacks = [];
// 这里需要bind this,否则new实例过程中立即调用func函数,此时还没有this
// func(this.resolve.bind(this), this.reject.bind(this)) // 传入后立即执行
try {
func(this.resolve.bind(this), this.reject.bind(this));
} catch (error) {
// 如果报错,直接执行 reject
this.reject(error);
}
}
// resole和reject是在创建 promise 的过程中调用的
resolve(result) {
// result 为 new Promise 时 resolve(result)中的result
setTimeout(() => {
// resolve 时,如果状态为 pendding,则改为 fulfilled
if (this.status === Commitment.PENDING) {
this.status = Commitment.FULFILLED;
this.result = result;
// 如果是异步,resolve可能会比 then 后执行
// 检查 callbacks数组并执行
this.resolveCallbacks.forEach((callback) => {
callback(result);
});
}
});
}
reject(result) {
// reject 的时候,如果状态为 pendding,则改为 rejected
setTimeout(() => {
if (this.status === Commitment.PENDING) {
this.status = Commitment.REJECTED;
this.result = result;
this.rejectCallbacks.forEach((callback) => {
callback(result);
});
}
});
}
// then 有两个参数,
// onfulfilled:状态成功时,执行的回调
// onrejected: 状态为拒绝时,执行的回调
then(onFULFILLED, onREJECTED) {
return new Commitment((resolve, reject) => {
// 判断传入的是否是函数
if (typeof onFULFILLED !== "function") {
onFULFILLED = () => {};
}
if (typeof onREJECTED !== "function") {
onREJECTED = () => {};
}
// 如果是 pendding,说明resolve被异步了,
// 把 then 应该执行的方法放到 resolveCallbacks中
if (this.status === Commitment.PENDING) {
this.resolveCallbacks.push(onFULFILLED);
this.rejectCallbacks.push(onREJECTED);
}
// 如果promise实例执行的是 resolve,则
if (this.status === Commitment.FULFILLED) {
setTimeout(() => {
onFULFILLED(this.result);
});
}
// 如果promise实例执行的是 reject,则
if (this.status === Commitment.REJECTED) {
setTimeout(() => {
onREJECTED(this.result);
});
}
});
}
}
let commitment = new Commitment((resolve, reject) => {
// resolve实际做了两件事
// 1.把 promise实例内部的 pedding状态改为 fulfilled
// 2.把 resolve(参数)的参数传入了promise实例,作为result
resolve("resolve的结果"); // 这里会立即执行 resolve方法
// reject()
// throw new Error('报错')
});
// commitment.then(
// undefined,
// res => {
// console.log('reject的时候会触发', res);
// }
// )
console.log("1");
let commitment2 = new Commitment((resolve, reject) => {
// func 会立即执行
console.log("2");
setTimeout(() => {
resolve("3"); // 把 resolve 的内容存在 result 中了
reject("4");
console.log(5);
});
});
commitment2.then(
(result) => {
console.log(result, "6");
},
(result) => {
console.log(result, "7");
}
);
console.log("8");
```
- JavaScript
- 1.数组
- 1.数组Api
- 2.判断是否为数组
- 3.手写forEach, map, filter, every, some, reduce
- 4.类数组转化为数组
- 5.reduce实现compose函数
- 7.sort实现与排序
- 2.类型
- 1. let, const, var
- 1. Number 数字
- 3. Boolean 布尔值
- 4. undefined和null
- 2. String 字符串
- 1. 字符串方法
- 2. 操作字符串实例
- 3. startWith&字符串模板
- 5. 类型转换
- 4.深拷贝与浅拷贝
- 7.Symbol类型
- typeof 和 instanceof
- Set
- Map
- 3.this,原型,原型链
- 1.this
- 2.手写call, apply, bind
- 3.模拟new操作符
- 4.手写Object.create
- 4.对象
- proxy代理
- defineProperty数据劫持
- 4.模块化
- 5.http
- ECMAScript
- 0. 调试&兼容性&错误处理
- 3. 运算
- 4. 对象(三种引用类型&正则)
- 1. 数组
- 1. 数组的六种遍历方法
- 2. 数组的增删查改
- 3. 操作数组(展开、join、排序...)
- 4. 补充五种ES6方法
- 2. 函数
- 3. JSON
- 4. 正则
- 附:正则表达式特殊字符
- 5. 面向对象
- es6的继承
- 6. 控制语句
- 7. ajax
- 8. promise
- 9. 闭包
- 1. 闭包产生三个相同随机数
- 2. 闭包实现点赞
- 10.箭头函数
- _isEmpty
- Object.assign(target, obj, obj)
- Math.ceil, round,
- DOM
- 3.1 节点
- 3.2 DOM操作元素
- 3.3 fragment DOM碎片
- 5. 事件
- BOM
- 1. window
- 2. navigation检测访问类型
- 3. screen窗口大小内容大小
- 4. history
- promise
- 1.promise使用
- 2.手写promise
- 3.手写promise.all
- 生成器generator
- 1.generator的使用
- 2.简单实现generator
- 手写async await
- async/await
- 5.防抖节流
- 难点深入
- 1. 浏览器&js特点
- 2. JS堆栈与深浅拷贝
- 3. 详解a++和++a的区别
- 4. JS&jQuery获取元素的方法
- 5. NodeList和HTMLCollection区别
- 6. var与let的区别
- 7. this 与 bind call apply
- 8. get与post请求的区别
- 9. 闭包
- Dom demo
- 1. JQuery--页面点击切换效果
- 2. JQuery-load实现头尾封装
- 3. JS--添加移除属性名
- 4. jQuery--eq()与index()
- 5. table隔行变色
- 6. 改变函数this的指向
- 7. jQuery each遍历
- ECMAScript demo
- 1. 斐波那契数列
- 2. 数组去重
- 3. 自调用函数生成随机数
- 浏览器、DOM
- 1.从输入url到页面加载的全过程
- 2.http与https
- 3.v8垃圾回收机制
- 4.dom事件
- 5.跨域
- 6.强缓存和协商缓存
- 3.eventloop,宏任务和微任务
- 1.什么是任务
- 2.执行顺序例题
- 3.执行顺序例题,添加script
- 4.执行顺序,多个宏任务
- 4.HTTP
- 1.经典五层模型
- 2.http发展历史
- 3.http三次握手
- 4.URI,URL,URN
- 1.http协议
- 2.https
- http状态码
- 5.script标签defer和async区别
- cookie
- connect: keep-alive