promise实现了哪些功能?只有实现一个promise才能算真正的了解。。。
首先要理解一些概念。
promise 的异步执行,具体哪些部分异步执行了?
promise 内的 resolve(作为一个回调函数)肯定是异步执行的,但是给 promise 直接传递的函数并没有异步执行。
then 的回调函数也异步执行,那是因为 resovle 异步执行了,而 then 函数本身是同步调用的。
const p = new Promise(resolve => {
// 这个函数体同步执行
// 这个 resolve 在 promise 内将被异步调用
resolve();
});
// 这个 then 肯定是同步调用,因为 js 本身就是同步执行
p.then((v) => {
// 这里的函数体是异步执行的,因为 resolve 是被异步调用的
});
promise 返回一个 promise 实例,调用 then 也同样返回一个 promise 实例。而 then 返回的是一个新的实例。
const p = new Promise(resolve => {
});
const _p = p.then((v) => {
});
// false
console.log(p === _p);
实现一个 promise?
// 三种状态
const padding = 'padding';
const success = 'success';
const fail = 'fail';
class MyPromise {
// resolve 的值,实际上闭包即可,不需要专门维护
value;
// 三种状态
state;
// 注册 then 的 callback
taskList = [];
constructor(fn){
// 创建 resolve 和 reject
const resolve = (v) => {};
const reject = (err) => {};
// 默认状态
this.state = padding;
// 同步执行,但在 promise 内部只是注入了2个方法
fn(resolve, reject);
}
}
// 普通调用,创建实例
const p = new MyPromise((resolve) => {
resolve(1);
});
resolve 方法在 promise 内是异步调用;如果不调用 then,promise 的返回结果也会创建出来。这说明 resolve 方法:
const resolve = (v) => {
// 模拟异步,实际上应该用微任务的 MutationObserver
setTimeout(() => {
this.value = v;
});
};
then 方法有多个意义:
- then 函数只是在 promise 上注册了一些回调。
- 这些回调是接收 resolve 调用后的参数。
- 最终返回了一个新的 promise。
- then 不传任何参数等同于一次透传。
// 数字注释代表解决问题的序号
// 4
then(fn = v => v){
// 3
// 返回的是一个 promise
return new Promise((resolve) => {
// fn 肯定不是立即执行,所以放到一个 taskList 中
// 这里是同步执行的,所以放在 promise 里也不影响,如果拿到 promise 外面不好组织
// 1
this.taskList.push((_v) => {
// 这个匿名函数,实际上就是把 fn 封装了一层
// 因为这里 resolve 需要拿到 fn 的执行结果
// 它将在未来被调用,所以会拿到结果
// 2
const result = fn(_v);
resolve(result);
});
});
}
回看 resolve,它应该解决的问题是,我注册了多个 then,那么应该依次执行 then 的回调。
且一旦调用 resolve,将更改 promise 的状态,且无法多次调用
const resolve = (v) => {
// 如果状态被改变,则什么都不做
if (this.state !== padding) {
// 它当然需要同步判断
return;
}
// 调用 resolve 时,锁定状态
this.state = success;
// 模拟异步,实际上应该用微任务的 MutationObserver
setTimeout(() => {
// taskList 是 注册 then 的 callback
// task 是 then 方法中被封装的 fn
this.taskList.forEach(task => task(v));
});
};
此时的 promise 基本满足 resolve、then 的基本调用了。
promise 实际还有很多功能和实现,比如 then 返回一个函数,或者返回一个对象且此对象拥有 then 方法,或则返回一个 promise,那么这个 promise 链还会延长。但暂时不实现这些细节。
catch ...to be continue
|