最近看到一段语句,分享给在看的你:小时候,哭是解决问题的法宝,长大后,笑是面对生活的武器。 使用方式:
let promise1 = new Promise((resolve, reject) => {
resolve(1)
});
promise1.then(res => console.log(res))
分析: new Promise(xxx)返回一个对象promise1,promise1.then(()=>{}, ()=>{}),当前方的a函数中调用了resolve(promise1的结果),那么then中的函数就会被执行。 resolve怎么来的,势必是原型上的,then方法中的函数参数,势必是被加入到实例的属性上了,且加入到前面实例的方法中还存储着改变当前then返回的这个promise实例的能力;
/*
* @Author: zhangbuzhou
* @Date: 2021-07-24 21:42:47
* @LastEditTime: 2021-07-24 22:01:47
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \myvue-project-runtime-only\src\utils\MyPromise.js
*/
function MyPromise(executor) {
this.value = "";
this.status = "pending"; // resolved、rejected
this.onResolvedCallbackArr = []; // 实例promise1可以调用多次then方法
this.onRejectedCallbackArr = [];
// 异步结束:成功,改变实例状态,调用then中回调
const resolve = (response) => {
setTimeout(() => {
// promise实例的状态改变后,就不可再改变,这里只做了简单限制,
// 我觉得还可以使用object.defineproperty将status属性改为无法使用赋值改变
if (this.status === "pending") {
this.value = response;
this.status = "resolved";
// 如果实例后面调用了then方法,此时已经加入到fulfiledCallbackArr数组当中
this.onResolvedCallbackArr.forEach((callback) => {
callback(response);
});
}
}, 0);
};
const reject = (error) => {
setTimeout(() => {
// 同resolve
if (this.status === "pending") {
this.value = error;
this.status = "rejected";
this.onRejectedCallbackArr.forEach((callback) => {
callback(error);
});
}
});
};
try {
executor(resolve, reject);
} catch (err) {
reject(err);
}
}
// 当promise实例 A 调用then方法,其实是将一个回调加入到这个promise实例 A 当中,
// 当这个实例 A 的异步结束后,也就是调用了resolve,改变状态的同时会调用then中写的回调函数
// 这个回调函数又可以调用then方法创建的实例 B 的resolve改变状态,改变状态的同时,还会调用B实例的then中回调
// 这样就实现了链式回调
MyPromise.prototype.then = function(resolveFn, rejectFn) {
return new MyPromise((resolve, reject) => {
// 防止then中参数不是或者没传函数,保证即使then中没传参数,也可以继续链式调用
typeof resolveFn === 'function' ? null : resolveFn = res => res;
typeof rejectFn === 'function' ? null : rejectFn = err => err;
this.fulfiledCallbackArr.push(() => {
try {
let result = resolveFn(this.value);
// 如果then中函数返回的是一个promise实例,那么此promise实例的状态依据这个返回值result的状态
// 这里是重点,理解then的作用,就可理解result.then(resolve)是为何了
result instanceof MyPromise ? result.then(resolve) : resolve(result);
} catch (err) {
reject(err);
}
});
this.rejectedCallbackArr.push(() => {
try {
let result = rejectFn(this.value);
result instanceof MyPromise ? result.then(resolve) : resolve(result);
} catch (err) {
reject(err);
}
});
});
};
// 上面的then方法,在pending状态时,添加的监听函数能够在状态改变时得到响应,
// 当状态已经改变时,直接then会立即添加一个微任务,所以完整版的话还需要判断promise的状态
// 理解了上述,再实现promise的一些静态方法
MyPromise.all = function (promiseArr) {
let len = promiseArr.length;
let result = [];// 保存每个实例的结果
return new MyPromise((resolve, reject) => {
promiseArr.forEach(promiseObj => {
promiseObj.then(res=> {
len --;
result.push(res);
if(!len) {
resolve(result);
}
})
})
})
}
MyPromise.resolve = function (value) {
return value instanceof MyPromise
? new MyPromise((resolve, reject) => value.then(resolve, reject))
: new Promise((resolve) => resolve(value));
};
MyPromise.reject = function (value) {
return value instanceof MyPromise
? new MyPromise((resolve, reject) => value.then(resolve, reject))
: new Promise((resolve, reject) => reject(value));
};