2022-12-30 Promise是构造函数,then()和catch()是绑定在原型上的方法,then的第二个参数和catch的区别,基于Promise处理AJAX请求

本文详细介绍了Promise作为构造函数的性质,探讨了Promise原型上的then和catch方法,包括它们的语法、作用及区别。特别强调了then的第二个参数与catch在捕获异常时的差异,并通过实际示例解释了如何基于Promise处理AJAX请求。重点讨论了then和catch捕获异常的就近原则以及返回值的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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);
  });
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端OnTheRun

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值