1.验证:Promise的本质是一个构造函数
var p = new Promise(function(resolve, reject) {
setTimeout(() => {
resolve("hello!!");
}, 1000);
});
p.then(res => {
console.log("成功的回调:", res);
});
p.catch(data => {
console.log("失败的回调:", data);
});
// 验证:p是实例,Promise是构造函数,then()和catch()是写在原型上的方法
console.log(p.__proto__ == Promise.prototype);//true
2.Promise的原型上绑定的属性和方法
2.1.Promise的原型上绑定的属性constructor指向new Promise出来的实例
var p = new Promise(function(resolve, reject) {
resolve("hello!!");
});
p.then(res => {
console.log("成功的回调:", res);
});
p.catch(data => {
console.log("失败的回调:", data);
});
// 验证:p是实例,Promise是构造函数,then()和catch()是写在原型上的方法
console.log(p.__proto__ == Promise.prototype);
console.log(Promise.prototype.constructor == p);
2.2.Promise的原型上绑定的方法then
语法
Promise.prototype.then(onFulfilled,onRejected)
其中,
onFulfilled是Promise变成fulfilled状态时调用的函数
onRejected是Promise变成rejected状态时调用的函数,这个rejected函数有一个reason参数,即"被拒绝的原因(rejection reason)",如果reason参数不是函数则会在内部替换成一个"thrower"函数
说明
添加解决(fufillment)到拒绝(rejection)的回调到当前Promise,返回一个新的Promise
示例
var p=new Promise((resolve,reject)=>{
resolve("ok!!!");//接受
//reject(new Error("not OK!!!"))
});
p.then(value=>{
console.log("成功的回调:",value);
},reason=>{
onsole.log("失败的回调:",reason);
});
当executor函数抛出错误或者返回一个拒绝的Promise时,then将返回一个拒绝的Promise
Promise.resolve().then(()=>{
throw new Error("not OK!");
}).then(value=>{
console.log("成功:",value);
},reason=>{
console.log(reason.toString())
});
2.3.Promise的原型上绑定的方法catch
语法
Promise.prototype.catch(onRejected)
其中,
参数onRejected是被调用的一个Function,该函数拥有一个参数,reason表示rejection(拒绝)的原因
返回值是返回一个Promise,并且处理拒绝的情况
概括
catch方法可以用于Promise组合中的错误处理,它的行为与Promise.prototype.then(undefined,onRejected)相同
描述
添加一个拒绝(rejection)的回调到当前Promise,并返回一个新的Promise,
当这个回调函数被调用,新Promise将以它的返回值来resolve,
否则如果当前Promise进入fulfilled状态,则以当前Promise的完成结果作为新Promise的返回结果
示例
var p=new Promise((resolve,rejected)=>{
resolve("ok!!!");
});
p.then(value=>{
console.log(value);
throw "notok?!";
});
p.catch(reason=>{
console.log(reason);
});
p.then(()=>{
console.log("123456"):
},()=>{
console.log("no error!");
});
//输出结果:notOK 123456
2.4.总结
方法 | 类型 | 说明 |
---|---|---|
Promise.prototype.then() | 原型方法 | 为Promise实例添加状态改变时的回调函数 |
Promise.prototype.catch() | 原型方法 | 为Promise实例指定发生错误时的回调函数 |
Promise.prototype.finally() | 原型方法 | 用于指定不管Promise对象的最后状态如何,都会执行的函数 |
Promise.resolve() | 构造函数方法 | 创建Promise成功的实例 |
Promise.reject() | 构造函数方法 | 创建Promise失败的实例 |
Promise.all() | 构造函数方法 | 接收一个包含多个Promise对象的数组,等待所有都完成时,返回存放他们结果的数组,如果任意一个被拒绝则立即抛出错误,其他已完成的结果会被忽略 |
Promise.race() | 构造函数方法 | 接收一个包含多个Promise对象的数组,等待第一个有结果(完成或拒绝)的Promise,把其result/error作为其结果返回 |
3.then的第二个参数和catch有什么区别?
主要区别
then的第一个参数抛出的异常,第二个参数捕获不到,
后面的catch可以捕获到,或者第二个then的第二个参数可以捕获到
3.1.then的第一个参数抛出的异常,第二个参数捕获不到
const p = new Promise((resolve, reject) => {
resolve() //抛出成功时的结果
});
p.then((res) => {
throw new Error("hello");
}, res2 => {
console.log(res2);//捕获不到:报错
})
3.2.then的第一个参数抛出的异常,后面的catch可以捕获到
const p = new Promise((resolve, reject) => {
resolve() //抛出成功时的结果
});
p.then((res) => {
throw new Error('hello');
}).catch((err1) => {
console.log(err1, 'err1')
});
3.3.then的第一个参数抛出的异常,第二个then的第二个参数可以捕获到
const p = new Promise((resolve, reject) => {
resolve() //抛出成功时的结果
});
p.then((res) => {
throw new Error('hello');
}).then(() => {}, (err2) => {
console.log(err2, 'err2')
});
3.4.then的第二个参数和catch捕获异常时会采取就近原则
当两者都存在时,则只有then的第二个参数能捕获到,
如果then的第二个参数不存在,则catch方法会捕获到
const p1 = new Promise((resolve, reject) => {
resolve() //抛出成功时的结果
});
p1.then((res) => {
throw new Error('hello');
}).then(() => {}, (err2) => {
console.log(err2, 'err2');//就近原则:err2会捕获到错误
}).catch((err1) => {
console.log(err1, 'err1');
});
const p2 = new Promise((resolve, reject) => {
resolve() //抛出成功时的结果
});
p2.then((res) => {
throw new Error('hello');
}).catch((err1) => {
console.log(err1, 'err1');//就近原则:err1会捕获到错误
}).then(() => {}, (err2) => {
console.log(err2, 'err2');
});
4.基于Promise处理AJAX请求
4.1.封装Promise函数处理原生Ajax请求
function queryData() {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState != 4) return; //不做处理
if (xhr.status == 200) resolve(xhr, responseText);//处理正常的情况
else reject("出错了"); //处理异常的情况
};
xhr.open("get", "/data");
xhr.send(null);
});
}
4.2.then参数中的函数返回值
4.2.1.返回Promise实例对象
queryData("http://localhost:3000/data")
.then(function (data) {
console.log(data);
})
.catch(function (info) {
console.log(info);
});
4.2.2.返回普通值(返回的普通值会直接传递给下一个then,通过then参数中函数的参数接收该值)
//发送多个ajax请求并且保证顺序
queryData("http://localhost:3000/data")
.then(function (data) {
console.log(data);
return qureyData("http://localhost:3000/data1");
})
.then(function (data) {
console.log(data);
return qureyData("http://localhost:3000/data2");
})
.then(function (data) {
console.log(data);
});