Promise
Promise 是一个对象,它代表了一个异步操作的最终完成或者失败。由于它的then方法和catch、finally方法会返回一个新的Promise所以可以允许我们链式调用,解决了传统的回调地狱问题。
再说一下then以及catch方法:
1. Promise的状态一经改变就不能再改变。
2. .then和.catch都会返回一个新的Promise。
3. catch不管被连接到哪里,都能捕获上层未捕捉过的错误。
4. 在Promise中,返回任意一个非 promise 的值都会被包裹成 promise 对象,例如return 2会被包装为return Promise.resolve(2)。
5. Promise 的 .then 或者 .catch 可以被调用多次, 但如果Promise内部的状态一经改变,并且有了一个值,那么后续每次调用.then或者.catch的时候都会直接拿到该值。
6. .then 或者 .catch 中 return 一个 error 对象并不会抛出错误,所以不会被后续的 .catch 捕获。
7. .then 或 .catch 返回的值不能是 promise 本身,否则会造成死循环。
8. .then 或者 .catch 的参数期望是函数,传入非函数则会发生值透传。
9. .then方法是能接收两个参数的,第一个是处理成功的函数,第二个是处理失败的函数,再某些时候你可以认为catch是.then第二个参数的简便写法。
10. .finally方法也是返回一个Promise,他在Promise结束的时候,无论结果为resolved还是rejected,都会执行里面的回调函数。
再说一下finally方法:
1. .finally()方法不管Promise对象最后的状态如何都会执行
2. .finally()方法的回调函数不接受任何的参数,也就是说你在.finally()函数中是没法知道Promise最终的状态是resolved还是rejected的
3. 它最终返回的默认会是一个上一次的Promise对象值,不过如果抛出的是一个异常则返回异常的Promise对象。
最后说一下all以及race方法:
1. Promise.all()的作用是接收一组异步任务,然后并行执行异步任务,并且在所有异步操作执行完后才执行回调。
2. .race()的作用也是接收一组异步任务,然后并行执行异步任务,只保留取第一个执行完成的异步操作的结果,其他的方法仍在执行,不过执行结果会被抛弃。
3. Promise.all().then()结果中数组的顺序和Promise.all()接收到的数组顺序一致。
4. all和race传入的数组中如果有会抛出异常的异步任务,那么只有最先抛出的错误会被捕获,并且是被then的第二个参数或者后面的catch捕获;但并不会影响数组中其它的异步任务的执行。
手写实现:
function Promise(exector) {
let self = this;
//status表示一种状态
let status = "pending";
let value = undefined;
let reason = undefined;
//成功执行
function resolve(value) {
if (status == 'pending') {
self.value = value;
self.status = "resolve";
}
}
//执行失败
function reject(reason) {
if (status == 'pending') {
self.reason = reason;
self.status = "reject"
}
}
//对异常操作
try {
exector(resolve, reject)
} catch (e) {
reject(e)
}
//设置promise的then方法
Promise.prototype.then = function(reject, resolve) {
let self = this;
if (this.status == 'resolve') {
reject(self.value)
}
if (this.status == 'reject') {
resolve(self.reason)
}
}
}
//new 一个promise 进行测试
let promise = new Promise((reject, resolve) => {
resolve("return resolve");
});
promise.then(data => {
console.log(`success${data}`);
}, err => {
console.log(`err${err}`);
})