文章目录

开篇点题,最近复习了前端技术点中有关 promise 的相关知识,但是还从未深入过源码,从未手写过 promise,项目中已经全面使用 promise 作为异步编程的解决方式,避免了回调地狱。
为了深入理解 promise 的工作原理,决定写一个关于"手写promise"的系列教程,希望自己能坚持写完,不要半途而废。
当然,你要说哪里会用到"手写promise",我只能告诉你:面试。
好了,话不多说,先来熟悉一下 promise 的基础知识。
一、实例对象promise的属性
打印一个promise
let p = new Promise((resolve, reject) => {
resolve("OK");
})
console.log(p);
如图所示,promise实例对象有两个实例属性:
-
PromiseState,保存的是promise对象的状态,有三个值分别是
pending(等待)
、fulfilled也称resolved(成功)
、rejected(失败)
。
promise的状态只能改变一次,从pending-->fulfilled
或者从pending-->rejected
。fulfilled 和 rejected 两种状态之间无法转换。
转变为成功状态时,成功结果的数据一般称为 value,转换为失败状态时,失败结果的数据一般称为 reason。 -
PromiseResult,保存成功或者失败的结果数据。
二、promise的工作流程
三、Promise API
1. Promise 构造函数
function Promise(excutor){ excutor(resolve, reject) }
new Promise((resolve, reject) => {
resolve("OK");
})
-
excutor函数:被称作执行器函数
(resolve, reject) => {}
,在 new Promise() 时同步执行。 -
resolve函数:Promise 构造函数内部定义的函数,调用时,将内部 pending 状态变为成功 fulfilled,
resolve(value)
。 -
reject函数:Promise 构造函数内部定义的函数,调用时,将内部 pending 状态变为失败 rejected,
reject(reason)
。说明:excutor执行器函数在 Promise 内部同步调用,异步操作在excutor执行器函数中执行。
2. Promise.prototype.then()方法
Promise.prototype.then = (onResolved, onRejected) => {}
p.then(value => {}, reason => {})
-
onResolved函数:成功的回调函数,
value => {}
-
onRejected函数:失败的回调函数,
reason => {}
说明:返回一个新的promise对象。then方法中有两个参数,分别为两个回调函数;onResolved为成功时的回调函数,得到resolve(value)中的value值;onRejected为失败时的回调函数,得到reject(reason)中的reason值。
成功的示例:
let p = new Promise((resolve, reject) => {
resolve("OK");
})
p.then(value => {
console.log(value); // OK
}, reason => {
console.log(reason);
})
console.log(p)
失败的示例:
let p = new Promise((resolve, reject) => {
reject("NO");
})
p.then(value => {
console.log(value);
}, reason => {
console.log(reason); // NO
})
console.log(p)
3. Promise.prototype.catch()方法
Promise.prototype.catch = (undefined, onRejected) => {}
p.catch(reason=>{})
-
onRejected函数:失败的回调函数
说明:返回一个失败的promise对象。
let p = new Promise((resolve, reject) => {
reject("NO");
})
p.then(value => {
console.log(value);
}).catch(reason => {
console.log(reason); // NO
})
console.log(p)
4. Promise.resolve()方法
Promise.resolve = (value) => {}
-
value参数:非 promise 类型对象
||
一个 promise 对象说明:返回一个成功或者失败的 promise 对象。如果传入的参数为非 promise 类型的对象,则返回结果为成功的 promise 对象;如果传入的参数为 promise 对象,则传入参数的 promise 对象的结果决定了 resolve 返回的 promise 对象的结果。
let p1 = Promise.resolve()
let p2 = Promise.resolve(null)
let p3 = Promise.resolve("111")
let p4 = Promise.resolve(new Promise((resolve, reject) => {
resolve("OK")
}))
let p5 = Promise.resolve(new Promise((resolve, reject) => {
reject("NO")
}))
console.log(p1);
console.log(p2);
console.log(p3);
console.log(p4);
console.log(p5);
5. Promise.reject()方法
Promise.reject = (reason) => {}
-
reason参数:失败的原因
说明:返回一个失败的 promise 对象;不管传入的参数是什么,结果永远都是失败的;即使你传入一个成功的 promise 对象,Promise.reject 返回的结果也是失败的。
let p1 = Promise.reject()
let p2 = Promise.reject(null)
let p3 = Promise.reject("111")
let p4 = Promise.reject(new Promise((resolve, reject) => {
resolve("OK")
}))
let p5 = Promise.reject(new Promise((resolve, reject) => {
reject("NO")
}))
console.log(p1);
console.log(p2);
console.log(p3);
console.log(p4);
console.log(p5);
下图标红框的需要着重理解一下!!!
这里的报错是因为没有添加处理reject失败的回调函数,写个catch捕获一下失败信息就不会报错了。
6. Promise.all()方法
Promise.all = (promiseArray) => {}
-
promiseArray参数:包含 n 个 promise 对象的数组
说明:返回一个新的promise对象,promise对象的结果为一个数组;只有所有的promise对象都成功才成功,只要有一个失败了就失败。
成功的示例:
let p1 = new Promise((resolve, reject) => {
resolve("111")
});
let p2 = Promise.resolve("222");
let p3 = Promise.resolve("333");
let p = Promise.all([p1, p2, p3]);
console.log(p);
失败的示例:
let p1 = new Promise((resolve, reject) => {
resolve("111")
});
let p2 = Promise.reject("error");
let p3 = Promise.resolve("333");
let p = Promise.all([p1, p2, p3]);
console.log(p);
7. Promise.race()方法
Promise.race = (promiseArray) => {}
-
promiseArray参数:包含 n 个 promise 对象的数组
说明:返回一个新的promise对象;第一个完成的promise对象的结果就是最终的结果。
同步执行,p1先执行,所以返回p1的结果"111":
let p1 = new Promise((resolve, reject) => {
resolve("111")
});
let p2 = Promise.resolve("222");
let p3 = Promise.resolve("333");
let p = Promise.race([p1, p2, p3]);
console.log(p);
这里p1变为了异步执行,按顺序先执行p2,p2执行最快,所以结果为"222":
let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("111");
})
});
let p2 = Promise.resolve("222");
let p3 = Promise.resolve("333");
let p = Promise.race([p1, p2, p3]);
console.log(p);