一. promise对象的理解?
ES6 规定,Promise对象是一个构造函数,用来生成Promise实例,里面保存着某个未来才会结束的事件。
Promise 是异步编程的一种解决方案,比传统的异步解决方案【回调函数】和【事件】更合理、更强大。
promise对象里面接收一个函数作为参数,该函数的两个参数分别是reject和resolve,reject和resolve是js引擎提供的两个方法。
reject的作用是将promise对象的状态从‘未完成’变为‘失败’,在异步操作失败时调用,并将异步操作报错作为参数传递出去。
resolve的作用是当promise对象状态从“未完成”变为“成功”时调用,并将异步操作的结果作为参数传递出去。
promise对象里面还提供了.then 和 .catch的方法,分别用来接收promise对象返回的结果。
二.promise的特点?
1、自己身上有 all、reject、resolve 这几个方法
2、原型上有 then、catch 等方法
3、一旦建立,就无法取消,这是它的缺点 ,
4、对象的状态不受外界影响。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
5、一旦状态改变,就不会再变,任何时候都可以得到这个结果。
三.promise对象的方法?
1.Promise.resolve()方法
解释: Promise.resolve()是promise对象上的方法 作用:当传入的是promise对象的时候,他会返回这个promise对象 可以快速得到一个promise对象 当resolve方法中传入的非promise对象的时候,他会返回成功的promise对象。
const p = Promise.resolve(
new Promise((resolve, reject) => {
resolve(22);
})
);
console.log(p);
2.Promise.reject方法
解释:作用:快速返回一个promise对象,返回的promise对象的状态是失败的 返回的promise对象的结果是当前传入的值
const p = Promise.reject(
new Promise((resolve, reject) => {
resolve("succeed");
})
);
console.log(p);
console.log(Promise.reject(222));
3.Promise.all()方法
解释:总结: promise.all()方法的作用也是返回一个promise对象 promise.all()里面接收一个数组,数组里可以是多个promise对象。 当数组中传入的所有的promise对象都是成功状态的时候,返回的新的promise对象的状态是成功,值是当前传入的promise对象值的数组集合。 当数组中传入的promise对象中有一个状态是失败,返回的新的promise对象状态是失败,值是失败的那个promise的值 当数组中传入的promise对象中一个状态是padding,返回的新的promise对象状态是padding,值是undifind
const p1 = Promise.resolve("succeed");
const p2 = Promise.resolve("111");
const p3 = Promise.reject(222);
// const p4 = new Promise(()=>{
// })
const all = Promise.all([p1, p2, p3]);
console.log(all);
4.Promise.race()方法
解释:promise.race()方法的作用是返回先执行的那个promise对象
const p3 = Promise.reject(222);
const p1 = Promise.resolve("succeed");
const p2 = Promise.resolve("111");
const p4 = new Promise(() => {
setTimeout(() => {
resolve(333);
}, 1000);
});
const all = Promise.race([p4, p3, p2, p1]);
console.log(all);
四.promise原型的方法?
1.Promise.prototype.then()方法
解释:then方法是定义在原型上的,供实例对象调用。当Promise实例状态改变时,通过调用then方法添加回调函数,then方法中接受两个回调函数,第一个是成功回调,第二个是失败回调。 调用then方法返回新的promise实例对象,当我们在当前的then方法后面再次.then的时候,此时后面的.then会等待上一次执行完成,并把执行的结果传入下一次.then的回调函数中,每一次的.then被执行promise的状态都会改变。
const P = new Promise((resolve, reject) => {
resolve(111);
});
console.log(P.then()); //Promise对象
P.then(
(res) => {
console.log(res); //111
return res+111
},
(err) => {
console.log(err);
}
).then((r)=>{
console.log(r); //222
})
2.Promise.prototype.catch()方法
当promise实例的状态变成rejected的时候,这个时候catch方法可以捕获到这个错误,同时在then方法中如果抛出的错误也会被catch方法捕获。下面的代码中,Promise 在resolve语句后面,再抛出错误,不会被捕获,等于没有抛出。因为 Promise 的状态一旦改变,就永久保持该状态,不会再变了。
const p = new Promise((resolve, reject) => {
reject("error");
throw new Error("test");
});
p.then(
(res) => {
console.log(res);
},
(err) => {
console.log(err); // error
return x + 2;
}
).catch((err) => {
console.log(err); //x is not defined
});
Promise 对象的错误具有“冒泡”性质,会一直向后传递,直到被捕获为止。也就是说,错误总是会被下一个catch语句捕获。所以在书写时总是建议使用catch方法,而不是使用then方法的第二个参数。代码如下:
const p = new Promise((resolve, reject) => {
resolve(111);
});
p.then((res) => {
return res + 1;
})
.then((res) => {
return res + a;
})
.then((res) => {
return res + "x";
})
.catch((err) => {
console.log(err); //a is not defined
});
3.Promise.prototype.finally()方法
finally()方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。该方法是 ES2018 引入标准的。同时finally方法不接收任何参数,同时return出去的值,不会传入下一次的then方法中,这样使得它与promise的状态无关,不依赖于promise的执行结果。案例展示:
Promise.resolve(2)
.then((res) => {
setTimeout(() => {
console.log(1);
}, 2000);
return res + x;
})
.catch((err) => {
console.log(2);
return err;
})
.then((res) => {
console.log(3);
console.log(res); //x is not defined
return "aa";
})
.finally(() => {
console.log(4);
return "bb";
})
.then((res) => {
console.log(res); //aa
});
//解释:执行的顺序是 2,3,"x is not defined",4,aa,1,
五.promise的基础封装
function MyPromise(callback) {
//callback代表MyPromise中的回调函数
this.PromiseState = "pending"; //默认状态pending
this.PromiseResult = "undefined"; //默认是undefined
const _this = this;
callback(
// 定义resolve,当执行了resolve函数就改变状态,并赋值
function resolve(val) {
//为了让promise对象只执行一次,状态改变就不会再变
if (_this.PromiseState !== "pending") return;
_this.PromiseState = "fulfilled";
_this.PromiseResult = val;
//异步的时候promise状态改变,执行resolveFn回调,同步的时候由于状态改变不会执行resolveFn回调
if (_this.callback) {
_this.callback.resolveFn(val);
}
},
// 定义reject
function reject(val) {
if (_this.PromiseState !== "pending") return;
_this.PromiseState = "rejected";
_this.PromiseResult = val;
if (_this.resolveFn) {
_this.callback.rejectFn(val);
}
}
);
}
// 添加then方法
MyPromise.prototype.then = function (resolveFn, rejectFn) {
//判断当前的promise状态是否成功
if (this.PromiseState === "fulfilled") {
resolveFn(this.PromiseResult);
}
if (this.PromiseState === "rejected") {
resolveFn(this.PromiseResult);
}
//当promise是异步的时候,此时then方法中并不能拿到promise的值,可以使用callback对象存储下当前的then方法中的回调,当promise状态改变的时候再执行then方法
if (this.PromiseState === "pending") {
this.callback = {
resolveFn,
rejectFn,
};
}
};
const p = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve(222);
}, 2000);
// resolve(333);
// reject(000)
});
p.then((res) => {
console.log(res);
});