有关promise(解决异步请求问题)以及Axios(基于 promise 的 HTTP 库)的总结——附源码

本文介绍了Promise的概念和规范,包括四大术语、三种状态和两个事件,详细阐述了Promise的基本用法,特别是then的链式调用和catch的顺延机制。同时,文章还探讨了基于Promise的HTTP库Axios,讲解了其在浏览器和Node.js中的应用。

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

一. 何为promise

本意为承诺的意思;


在编程过程中,会出现异步代码和同步代码,而简单地说,promise的出现就是为了解决异步编程的问题,让异步编程代码变的更加优雅;


异步代码的解决方案:
解决方案有很多种,promise算一种;如下:

  1. 回调函数
  2. promise
  3. generator + co
  4. async + await(终极解决方案,让写异步代码就像写同步代码那么简单)

二. promise的相关规范

1. promise四大术语

  1. 解决(fulfill):指一个 promise 成功时进行的一系列操作,如状态的改变、回调的执行。虽然规范中用 fulfill 来表示解决,但在后世的 promise 实现多以 resolve 来指代之。
  2. 拒绝(reject):指一个 promise 失败时进行的一系列操作。
  3. 终值(eventual value):所谓终值,指的是 promise 被解决时传递给解决回调的值,由于 promise 有一次性的特征,因此当这个值被传递时,标志着 promise 等待态的结束,故称之终值,有时也直接简称为值(value)。
  4. 据因(reason):也就是拒绝原因,指在 promise 被拒绝时传递给拒绝回调的值。

2. promise三个状态

  1. Pending (等待状态):可以迁移至执行态或拒绝态
  2. Fulfilled (执行状态):不能迁移至其他任何状态,必须拥有一个不可变的终值
  3. Rejected (拒绝状态):不能迁移至其他任何状态,必须拥有一个不可变的据因
    在这里插入图片描述

3. promise两个事件

针对三种状态有如下两种转换方向:

  1. pending --> fulfilled (执行态)
  2. pending --> rejected (拒绝态)
  • 注意: 在状态改变时,在执行器中有两个参数,一个是resolve,一个是reject,他们两个都是函数,在等待到执行态转换过程中调用resolve,在等待到拒绝态转换过程中调用reject函数;

4. promise一个对象

  • 就是指promise对象;

三. promise的用法

1. 基本用法

  • 只有当代码中有异步代码的时候,才要想起使用promise

(1) 本质

  • Pormise本质就是一个构造器
  • 在使用的时候需要new一个promise:new Promise()

(2) 具体代码

var p1 = new Promise();
console.log(p1) //报错 TypeError: Promise resolver undefined is not a function

报错原因:
在创建promise时,需要给promise指定一个执行器,修改如下:

var p1 = new Promise(function (resolve,reject) {

});
console.log(p1) 

查看结果:
在这里插入图片描述
此结果说明我们已经创建好了promise对象,并且当前对象处于pending状态;

  • 继续编写代码如下:
var p1 = new Promise(function (resolve,reject) {
//表示由等待到了执行状态,里面的参数就是指 终值(value)
   resolve("买包包");
});
var p1 = new Promise(function (resolve,reject) {
//表示由等待到了拒绝状态,里面的参数就是指 拒因(reason)
   reject("没钱")
});

等待状态中只有两种可能转换状态,要么成功,要么失败;

let p1 = new Promise(function (resolve,reject) {
//增加一个判断来确定转换为哪种状态
    if(Math.random() > 0.5){
        resolve("包包")
    }else{
        reject("没线")
    }
})

(3)then方法

针对上面代码,如何获取终值(包包)或者拒因(没钱)呢?
此时我们就需要利用事件机制
解决方案:
针对3种状态,只有如下两种转换方向:

  1. pending --> fulfilled
  2. pendeing --> rejected

在状态转换的过程中,就会触发事件:

  • 如果是pending --> fulfiied,就会触发onFulFilled事件
  • 如果是pendeing --> rejected,就会触发onRejected事件

因此: 在调用resolve方法或者reject方法的时候,就一定会触发事件。
需要注册onFulFilled事件 和 onRejected事件
针对事件的注册,promise对象提供了then方法,如下:
在这里插入图片描述
针对 onFulFilled: 会自动提供一个参数,作为终值(value)
针对 onRejected: 会自动提供一个参数,作为据因(reason)

  • 注册事件如下:
let p1 = new Promise(function (resolve,reject) {
//状态转化只能选择一个 如果两种状态都写出来时会默认执行上面的状态,此时就是执行“包包”这个状态
    resolve("包包")
    reject("没钱")
})
p1.then((value)=>{
    console.log(value) //输出 包包
},(err)=>{
    console.log("..."+err)  //如果转换为拒绝状态,这个地方就会输出 ...没钱
});

2. then的链式调用(相对难)

在每一次执行.then的时候都会返回一个新的promise,而初始状态是pending,返回的新的promise也可以继续.then,这样就相当于可以一直.then下去,这就叫做then的链式调用;

如下:

let p1 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        resolve("ok")
    },2000)
})
let p2 = p1.then(result=>{
    console.log(result)  // ok
    return 123;  
},reason=>{
    console.log(reason)
})
p2.then((result)=>{
    console.log(result)  //123
},(reason)=>{
    console.log(reason)
})

注意:

  1. p1.then中不论哪个方法执行,只要不报错,新的p2promise状态都会变成成功态,而方法返回值就是p2promise的终值,如果 p1.then 中没有返回值,那么只要语句不报错,p2promise状态还会变成成功态,此时的终值就是undefined;
  2. 如果p1.then中的两个方法报错了,p2就转成失败的状态,而p2的终值就是报错的语句
new Promise(resolve => {
    setTimeout(()=>{
        resolve(10)
    },2000)
}).then(result=>{
    console.log(`成功:${result}`) // 成功:10
    return result * n;  // 报错  n is not defiend   这个then返回了一个失败的promise
},reason => {
    console.log(`失败:${reason}`)
}).then(result=>{
    console.log(`成功:${result}`)
    return result * 20;
},reason => {
    console.log(`失败:${reason}`); // 失败:ReferenceError: n is not defined
    return reason * 10;  // NaN 没有报错
}).then(result=>{
    console.log(`成功:${result}`); //成功:NaN
    return Promise.reject(result * 20)
},reason => {
    console.log(`失败:${reason}`)
    return Promise.resolve(reason * 10)
}).then(result=>{  //
    console.log(`成功:${result}`);
},reason => {
    console.log(`失败:${reason}`); // 失败:NaN
})

3. catch、then的顺延机制

如果then中成功或失败的方法没有设置, 会顺延到下一个then中查找;

如下:

new Promise((resolve,reject)=>{
    setTimeout(()=>{
        reject(10)
    },2000)
}).then(result=>{      //此then中没有拒绝状态的事件
    console.log(`成功:${result}`)
}).then(result=>{
    console.log(`成功:${result}`)
    return result*10
},reason => {
    console.log(`失败:${reason}`) // 失败:10
    return reason*20
}).then(null,reason => {
    console.log(`失败:${reason}`)
}).then(result=>{
    console.log(`成功:${result}`) // 成功:200
},reason => {
    console.log(`失败:${reason}`)
})

在then的链式调用机制中,两个事件参数(result和reason)如果只写执行状态的终值(result)那么后面的reason参数可以不写,也可以写为null,如

then(result=>{console.log(result)})
//或者
then(result=>{console.log(result)}null)

而如果只写拒绝状态的终值(reason),那么前面的reason要写为null,如

then(null,reason => {console.log(reason)})

此时要想不写前面的null,那么就引入了catch
简单的讲,就相当于catch 是then的语法糖
.then(null,reason=>{}) 就等价于catch(reason => {})

因此代码就演化为:

new Promise((resolve,reject)=>{
    setTimeout(()=>{
        resolve(10)
    },2000)
}).then(result=>{
    console.log(`成功:${result}`)
}).catch(reason => {
    console.log(`失败:${reason}`)
})

将相当于如果上面状态如果变为执行状态,就执行 .then 语句;如果变为拒绝状态,就执行 .catch 语句;

四. Axios的使用

1. 何为Axios

Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。

2. Axios的应用

直接上代码:

  • 服务端:
let express = require("express") //引入express模块
let cors = require("cors") //引入cors,解决跨域问题
let app = express(); //生成一个服务器
app.use(cors())  //使用cors解决跨域问题
app.get("/news",(req,res)=>{ //写一个路由
    res.json({  //返回一个json数据
        code:"1",
        msg:{
            name:"wangcai",
            age:100
        }
    });
});
app.listen(3000,()=>{   //监听一个端口
    console.log("3000 ok")
})
  • 客户端:
<body>
<button>获取数据</button>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script> //引入Axios的js包
<script>
    document.querySelector("button").onclick = function () {  //给button注册点击事件
    //向上面创建的api发送请求,返回值如果成功就走.then如果失败就走.catch
        axios.get("http://localhost:3000/news").then(res=>{  
            console.log(res.data)  //最终输出结果为 100
        }).catch(reason=>{
            console.log(reason)
        })
    }
</script>
</body>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值