https://www.jianshu.com/p/5a0e98606dbf
// promise是es6提出的将异步操作同步化的一个对象 pending fulfilled rejected
// 状态凝固 从pending变为fulfilled,调用resolve 执行.then里面的内容
// 从pending变为rejected 调用reject 执行.catch里面的内容
// promise一旦创建就会立即执行 内部一般会封装一个对于异步函数的处理 .then .catch里面是微任务 微任务会在当前宏任务执行完成下一个宏任务开始执行之前执行
// 由于p2返回的是另一个promise 导致p2自己的状态无效了,由p1的状态决定p2的状态,所以后面的then语句都变成针对后者p1,又过了2秒,p1变为rejected导致触发catch方法指定的回调函数
// 链式调用 多层回调嵌套变成了同一层 用同步的方式编写异步代码
// 极简的实现
// 上述代码很简单,大致的逻辑是这样的:
// 调用 then 方法,将想要在 Promise 异步操作成功时执行的 onFulfilled 放入callbacks队列,其实也就是注册回调函数,
// 可以向观察者模式方向思考;
// 创建 Promise 实例时传入的函数会被赋予一个函数类型的参数,即 resolve,它接收一个参数 value,
// 代表异步操作返回的结果,当异步操作执行成功后,会调用resolve方法,这时候其实真正执行的操作是将 callbacks 队列中的回调一一执行。
// 极简的实现+链式调用+延迟机制+状态//极简的实现+链式调用
// 至此,一个初具功能的Promise就实现好了,它实现了 then,实现了链式调用,实现了状态管理等等。但仔细想想,
// 链式调用的实现只是在 then 中 return 了 this,因为是同一个实例,调用再多次 then 也只能返回相同的一个结果,
// 这显然是不能满足我们的要求的。下一节,讲述如何实现真正的链式调用。
class Promise {
callbacks = [];
state = 'pending';//增加状态
value = null;//保存结果
constructor(fn) {
fn(this._resolve.bind(this));
}
then(onFulfilled) {
if (this.state === 'pending') {//在resolve之前,跟之前逻辑一样,添加到callbacks中
this.callbacks.push(onFulfilled);
} else {//在resolve之后,直接执行回调,返回结果了
onFulfilled(this.value);
}
return this;
}
_resolve(value) { // resolve同步执行
this.state = 'fulfilled';//改变状态
this.value = value;//保存结果
this.callbacks.forEach(fn => fn(value));
}
}
let p = new Promise(resolve => {
setTimeout(() => {
console.log('done'); // done
resolve('5秒');
}, 5000);
}).then(tip => {
console.log('then1', tip); // then1 5秒
}).then(tip => {
console.log('then2', tip); // then2 undefined
})
// promise的链式调用的关键所在 是在then方法中创建并返回一个新的promise实例
// then 方法传入的形参 onFulfilled 以及创建新 Promise 实例时传入的 resolve 放在一起,
// 被push到当前 Promise 的 callbacks 队列中,这是衔接当前 Promise 和后邻 Promise 的关键所在。
// 链式调用的真正意义
// 执行当前 Promise 的 onFulfilled 时,
// 返回值通过调用第二个 Promise 的 resolve 方法,传递给第二个 Promise,作为第二个 Promise 的值