Promise与axios

一:Promise

定义:Promise是JS中进行异步编程的新解决方案,代替了单纯使用回调函数。

1.1异步操作都有哪些?

  1. fs文件操作

    • require('fs').readFile('./index.html',(err,data)=>{})
  2. 数据库操作
  3. AJAX
    • $.get('/server',(data)=>{})
  4. 定时器
    • setTimeout(()=>{},2000)

具体表达:

  1. 从语法上讲:Promise是一个构造函数
  2. 从功能上讲:Promise对象用来封装一个异步操作并可以获取其成功\失败的结果值

1.2为什么要用Promise?

  1. 指定回调函数的方式更加灵活

  1. 支持链式调用,可以解决回调地狱问题

    1. 什么是回调地狱:回调函数嵌套调用,外部回调函数异步执行的结果是嵌套的回调执行的条件
    2. 回调地狱:不便于阅读、不便于异常处理

2.1定时器Promise案例:

// Promise 形式实现
// resolve 解决  函数类型的数据
// reject 拒绝  函数类型的数据
const p = new Promise((resolve,reject) => {setTimeout(() => {//获取1-100的一个随机数let n  = rand(1,100)//判断if(n <= 30){resolve(n) // 将 promise 对象的状态设置为 【成功】}else{reject(n) // 将 promise 对象的状态设置为 【失败】}},1000)
})//调用then 方法
p.then((value) => {alert('恭喜你中奖了!中奖数字为:',value)
},(reason) => {alert('再接再厉,您的数字为:',reason)
})

2.2fs读取文件

//Promise 形式
let p = new Promise((resolve , reject) => {fs.readFile('./resource/content.txt',(err, data) => {//如果出错if(err) reject(err)//如果成功resolve(data)})
})//调用 then
p.then(value => {console.log(value.toString())
}, reason => {console.log(reason)
})

2.3AJAX请求

const p = new Promise((resolve,reject) => {//1.创建对象const xhr = new XMLHttpRequest()//2. 初始化xhr.open('GET','https://api.apiopen.top/getJok')//3. 发送xhr.send()//4. 处理相应结果xhr.onreadystatechange = function(){if(xhr.readyState === 4){//判断相应状态码 2xxif(xhr.status >= 200 && xhr.status <300){//控制台输出响应体resolve(xhr.response)}else{//控制台输出相应状态码reject(xhr.status)}}}
})p.then(value=>{console.log(value)
},reason=>{console.log(reason)
})

2.4util.promisify方法封装fs读取文件操作:

//引入 util 模块
const util = require('util')
//引入 fs模块
const fs = require('fs')
//返回一个新的promise函数(可以避免自己手动封装)
let mineReadFile = util.promisify(fs.readFile)
mineReadFile('./resource/content.txt'.then(value => {console.log(value.toString())
}))

2.5封装AJAX请求

function sendAJAX(url){return new Promise((resolve,reject) => {//1.创建对象const xhr = new XMLHttpRequest()xhr.responseType = 'json'//2. 初始化xhr.open('GET',url)//3. 发送xhr.send()//4. 处理相应结果xhr.onreadystatechange = function(){if(xhr.readyState === 4){//判断相应状态码 2xxif(xhr.status >= 200 && xhr.status <300){//控制台输出响应体resolve(xhr.response)}else{//控制台输出相应状态码reject(xhr.status)}}}
})
}
sendAJAX('https://api.apiopen.top/getJok').then(value=>{console.log(value)
},reason=>{console.warn(reason)
})

3.1promise的状态改变

Promise实例对象中的一个属性 【PromiseState】

  • pending 未决定的(初始的)
  • resolved / fullfilled 成功
  • rejected 失败

Promise状态的改变

  1. pending变为resolved
  2. pending变为rejected

说明:只有这两种状态改变,并且一个promise对象只能改变一次

无论变为成功还是失败,都会有一个结果数据

成功的结果数据我们一般称为value,失败的结果数据一般称为reason

3.2Promise 对象的值

实例对象中的另一个属性 【PromiseResult】

保存着异步任务【成功/失败】的结果

  • resolve
  • reject

3.3Promise基本工作流程

解释:new Promise后在Promise内部封装自己的异步任务,之后执行异步任务,如果成功了执行resolve(),状态变为resoloved,之后通过then调用成功的回调函数,失败同样

3.4Promise的API

  1. Promise.resolve方法:属于promise函数对象,不属于实例对象

(value) => {}

​ value:成功的数据或者promise对象

​ 说明:返回一个成功/失败的promise对象

//如果传入的参数为非Promise类型的对象,则返回的结果为成功的promise对象
//如果传入的参数为Promise对象,则参数的结果决定了resolve的结果
let p1 = Promise.resolve(555)
//此时p1状态为resolved,值为555
let p2 = Promise.resolve(new Promise((resolve, reject) =>{reject('Error!')
}))
//此时P2的状态为rejected,值为Error
p2.catch(reason => {console.log(reason)
})
  1. Promise.reject方法同样属于函数对象,不属于实例对象

无论返回什么值都是失败值,状态都为失败

p3中状态值为失败,失败的结果为传入的那个成功的Promise对象

案例:

7.promise.race()

4.1Promise的几个关键问题

4.1.1.如何改变Promise的状态

4.1.2.一个promise指定多个成功/失败回调函数,都会调用吗

当promise改变为对应的状态时都会调用

4.1.3.改变Promise状态和指定回调函数谁先谁后?

4.1.4.promise.then()返回的新promise的结果状态由什么决定

4.1.5.promise如何串联多个操作任务

  1. promise的then()返回一个新的promise,可以开成then()的链式调用

  2. 通过then的链式调用串联多个同步/异步任务

4.1.6.处理穿透

  1. 当使用promise的then链式调用时,可以在最后指定失败的回调
  2. 前面任何操作除了异常,都会传到最后失败的回调中处理,前面的.then都没有作用

4.1.7.如何中断Promise链条?

只有一种方式,就是返回一个pedding状态的Promise对象

手写Promise

暂未实现…

5.1async函数

  1. 函数的返回值为promise对象
  2. promise对象的结果由async函数执行的返回值决定
async function main(){//1.如果返回的值是一个非Promise类型的数据  //return 521  //状态为成功  值为返回的这个值//2.如果返回的是一个Promise对象return new Promise((resolve,reject) => {//resolve('ok')   成功//reject('Error')   失败//3.抛出异常throw "oh NO"  //失败  值为抛出的这个值})
}

5.2.await表达式

  1. await右侧的表达式一般为promise对象,但也可以是其他的值
  2. 如果表达式是promise对象,await返回的是promise成功的值
  3. 如果表达式是其他值,直接将此值作为await的返回值
  4. 注意事项:
    • await必须写在async函数中,但async函数中可以没有await
    • 如果await的promise失败了,就会抛出异常,需要通过try…catch捕获处理
async function main(){let p = new Promise((resolve,reject) => {//resolve('ok')   下面的res返回的是okreject('Error')})//1.右侧是promise的情况let res = await p  //成功时为成功的值//2. 右侧为其他类型的数据let res2 = await 20  //返回20//3.如果promise是失败的状态try{let res3 = await p    }catch(e){console.log(e)  //返回Error}
}main()

async和await

//将resource目录下的1.html  2.html  3.html文件内容连接在一起
const fs = require('fs')
const util = require('util')
const mineReadFile =util.promisify(fs.readFile)
// fs.readFile('./resource/1.html',(err,data1) => {//     if (err) throw err
//     fs.readFile('./resource/2.html',(err,data2) => {//         if (err) throw err
//         fs.readFile('./resource/3.html',(err,data3) => {//             if (err) throw err
//             console.log(data1 + data2 + data3)
//         })
//     })
// })//async和await
async function main() {try{let data1 = await mineReadFile('./resource/1.html')let data2 = await mineReadFile('./resource/2.html')let data3 = await mineReadFile('./resource/3.html')console.log(data1 + data2 + data3)}catch (e) {console.log(e.code)}
}

async和await结合发送Ajax请求

<button id = 'btn'>点击获取段子</button>
function sendAJAX(url){return new Promise((resolve,reject) => {//1.创建对象const xhr = new XMLHttpRequest()xhr.responseType = 'json'//2. 初始化xhr.open('GET',url)//3. 发送xhr.send()//4. 处理相应结果xhr.onreadystatechange = function(){if(xhr.readyState === 4){//判断相应状态码 2xxif(xhr.status >= 200 && xhr.status <300){//控制台输出响应体resolve(xhr.response)}else{//控制台输出相应状态码reject(xhr.status)}}}
})
}let btn = document.querySelector('#btn')btn.addEventListener('click',async function(){let duanzi = await sendAJAX('http://api.apipoen.top/getJoke')console.log(duanzi)
})

二:Axios

概念:Axios是专注于网络数据请求的一个库

相比于原生的XMLHttpRequest对象,axios简单易用

相比于jQuery,axios更加轻量化,只专注于网络数据请求

1.1使用axios发起GET请求

axios发起get请求的语法:

axios.get('url',{params:{/*参数*/}}).then(callback)//实例代码
var url = 'http://www.liulongbin.top:3006/api/get'
//  请求的参数对象,请求参数  ?name= zs&age=20
var paramsObj = {name:'zs', age:20}
// 调用axios.get() 发起GET请求
axios.get(url, { params:paramsObj }).then(function(res){//res.data 是服务器返回的数据var result = res.dataconsole.log(res)
})

1.2使用axios发起POST请求

axios发起post请求的语法:

axios.post('url',{/*参数*/}).then(callback)

具体的请求示例如下:

//请求的url地址
var url = 'http://www.liulongbin.top:3006/api/post'
// 要提交到服务器的数据
var dataObj = { location : '北京' , address : '顺义'}
// 调用 axios.post() 发起POST请求
axios.post(url, dataObj).then(function(res){//res.data 是服务器返回的数据var result = res.dataconsole.log(result)
})

1.3直接使用axios发起请求

axios也提供了类似于jQuery中$.ajax()的函数,语法如下:

axios({method:'请求类型',url:'请求的URL地址',data:{/* POST数据  */},params:{/* GET参数 */}
}).then(callback)

直接使用axios发起GET请求

axios({method:'GET',url : 'http://www.liulongbin.top:3006/api/get',params:{//GET参数要通过params属性提供name:'zs',age:20}
}).then(function(res){console.log(res.data)
})

直接使用axios发起POST请求

axios({method:'POST',url:'http://www.liulongbin.top:3006/api/post',data:{// POST 数据要通过data属性提供bookname:'111',price:666}
}).then(function(res){console.log(res.data)
})

2.1axios基本使用

         //1.获取按钮const btns = document.querySelectorAll('button')//第一个btn[0].onclick = function () {// 发送AJAX请求axios({method:'get',//urlurl:'http://127.0.0.1:3000/posts/2'}).then(response => {console.log(response)})}//2.添加一篇新的文章btn[1].onclick = function () {// 发送AJAX请求axios({method:'post',//urlurl:'http://127.0.0.1:3000/posts',//设置请求体data:{title:'今天天气不错',author:'张三'}}).then(response => {console.log(response)})}//3.更新数据btn[2].onclick = function () {// 发送AJAX请求axios({method:'put',//urlurl:'http://127.0.0.1:3000/posts/3',//设置请求体data:{title:'今天天气不错',author:'左超然'}}).then(response => {console.log(response)})}//4.删除数据btn[3].onclick = function () {// 发送AJAX请求axios({method:'delete',//urlurl:'http://127.0.0.1:3000/posts/3',}).then(response => {console.log(response)})}

2.2axios其他方式发送请求

用axios.request({})方法

const btns = document.querySelectorAll('button')
//发送GET请求
btns[0].onclick = function(){//axios()axios.request({method:'GET',url:'http://127.0.0.1:3000/comments'}).then(response => {console.log(response)})
}

用axios.post()发送post请求,添加一条comments

const btns = document.querySelectorAll('button')
//发送GET请求
btns[0].onclick = function(){axios.post(url:'http://127.0.0.1:3000/comments',{"body":'喜大普奔',"postId": 2 }).then((response) => {console.log(response)})
}

3.1axios请求响应结果的结构

config:请求的配置对象

data:请求体中的内容(数据)

headers:请求头的内容

request:原生的AJAX请求内容

status:请求状态码

statusText:请求内容

4.1.axios配置对象详细说明

4.2.axios的默认配置

const bens = document.querySelectorAll('button')
//默认配置
axios.defaults.method = 'GET'  //设置默认的请求类型为GET
axios.defaults.baseURL = 'http://localhost:3000'  //设置基础URL
axios.defaults.params = {id:100}  //默认参数为id=100    http://127.0.0.1?id=100
axios.defaults.timeout =  3000  //超时时间为3s
btns[0].onclick = function(){axios({url:'/posts'}).then(response => {console.log(response)})
}

4.3.axios创建实例对象发送请求

const btns = document.querySelectorAll('button')
//创建实例对象
const duanzi = axios.create({baseURl:'https://api.apiopen.top',timeout: 2000
})
//此时duanzi是axios的一个实例对象,它和axios对象的功能几乎是一样的
//请求方式1
duanzi({url:'/getJoke'
}).then(response => {console.log(response.data)
})
//请求方式2
duanzi.get('/getJoke').then(response => {console.log(response.data)
})
//上述请求方式1和请求方式2效果一样

实例对象有什么作用?

如果我们的项目的接口不是来自于一个服务器,那么使用默认配置就不行了 因为默认配置前面的域名只能设置为一个,可以创建两个axios实例对象,分别用实例对象发起ajax请求

5.1.axios拦截器

axios拦截器分为请求拦截器和响应拦截器

//Promise
// 设置请求拦截器
axios.interceptors.request.use(function(config){console.log("请求拦截器 成功")config.params = {a:100}return config//throw 'error'  //抛出错误 之后后续的拦截器就只能走失败的拦截器了
},function(error){console.log('请求拦截器 失败')return Promise.reject(error)
})//设置相应拦截器
axios.interceptors.response.use(function(response){console.log('响应拦截器 成功')return response.data
},function(error){console.log('响应拦截器 失败')return Promise.reject(error)
})//发送请求
axios({method:'GET',url:'http://127.0.0.1:3000/posts'
}).then(response => {console.log('自定义回调处理成功的结果')
}).catch(reason => {console.log('自定义失败回调')
})

config参数:配置对象

可以修改config中的参数

response:响应体内容

如果一直都是成功的

如果请求拦截器中抛出了错误

如果有多个请求拦截器和响应拦截器 则请求拦截器后面的先执行 响应拦截器前面的先执行

6.1.axios取消请求

//获取按钮
const btns = document.querySelectorAll('button')
//2.声明全局变量
let cancel = null
//发送请求
btn[0].onclick = function(){axios({method:'GET',url:'http://localhost:3000/posts',//1.添加配置对象的属性cancelToken: new axios.CancelToken(function(c){//3.将c的值赋值给cancelcancel = c}).then(response =>{console.log(response)})})
}
btn[1].onclick = function(){cancel()
}

检测上一次的请求是否已经完成

//获取按钮
const btns = document.querySelectorAll('button')
//2.声明全局变量
let cancel = null
//发送请求
btn[0].onclick = function(){//检测上一次的请求是否已经完成if(cancel !== null){//如果没有完成 取消上一次的请求  cancel()}axios({method:'GET',url:'http://localhost:3000/posts',//1.添加配置对象的属性cancelToken: new axios.CancelToken(function(c){//3.将c的值赋值给cancelcancel = c}).then(response =>{console.log(response)//将cancel的值初始化设置cancel = null})})
}
cancel = c}).then(response =>{console.log(response)})
})

}
btn[1].onclick = function(){
cancel()
}


检测上一次的请求是否已经完成[外链图片转存中...(img-ijmF3poX-1663677739499)]```js
//获取按钮
const btns = document.querySelectorAll('button')
//2.声明全局变量
let cancel = null
//发送请求
btn[0].onclick = function(){//检测上一次的请求是否已经完成if(cancel !== null){//如果没有完成 取消上一次的请求  cancel()}axios({method:'GET',url:'http://localhost:3000/posts',//1.添加配置对象的属性cancelToken: new axios.CancelToken(function(c){//3.将c的值赋值给cancelcancel = c}).then(response =>{console.log(response)//将cancel的值初始化设置cancel = null})})
}

Promise和Axios相关推荐

  1. Ajax、Promise、Axios前端三剑客

    文章目录

  2. vue如何发送网络请求,使用axios事半功倍!

    目录 一.axios使用 1.支持多种请求方式: 2.安装 3.简单使用实例 4.发送并发请求 5.全局配置 二.axios的实例 1.为什么要创建 axios的实例呢? 2.使用 三..axios模 ...

  3. axios怎么封装,才能提升效率?

    大家好,我是若川.今天分享一篇axios封装的文章.学习源码系列.面试.年度总结.JS基础系列. 作为前端开发者,每个项目基本都需要和后台交互,目前比较流行的ajax库就是axios了,当然也有同学选 ...

  4. 浏览器 JavaScript HTTP 库的大比拼:SugerAgent VS Axios

    浏览器 JavaScript HTTP 库的大比拼:SugerAgent VS Axios Ajax 请求在现代网站中大量使用.除了使用执行Ajax请求的内置方法(XMLHttpRequest)外,许 ...

  5. ES6学习 - Promise对象

    Promise Promise是异步编程的一种解决方案,比传统的解决方案--回调函数和事件--更合理和更强大. 所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步 ...

  6. vue ----axios

    axios 只负责发送网络请求 基本使用 ① 导入库文件,可以在window全局使用axios() ②发送请求 axios({method: '请求的类型', //GETurl: '请求的 URL 地 ...

  7. Cli4.5.x 中使用axios请求数据

    Cli4.5.x 中使用axios请求数据 文章目录 Cli4.5.x 中使用axios请求数据 前言 一.安装并配置axios 1.安装axios 2.vue-axios 二.各种请求方法 三.请求 ...

  8. vue怎么获取axios的return值?

    代码: methods:{getNum(){axios({url: '/api/blog',method: 'GET'}).then((res) => {return res})},getDat ...

  9. Promise和事件循环

    01-Promise语法 1.1-Promise介绍 ES6教程传送门:http://es6.ruanyifeng.com/#docs/promise 1.Promise是什么? Promise 是 ...

最新文章

  1. numpy.ndarray的赋值操作
  2. 100多篇论文被知网擅自收录!89岁教授维权获赔70余万!
  3. PowerShell因为在此系统中禁止执行脚本
  4. PowerShell-1.入门及其常用
  5. css3 选择器_10-CSS3选择器详解
  6. javascript DOM事件总结
  7. Linux下rc.local不执行问题
  8. Could not find class
  9. ado创建mysql数据库_ADO创建数据库文件(*.MDB) | 学步园
  10. TCP编程、UDP编程
  11. DOS攻击之Synflood攻击
  12. 信息课为什么不叫计算机课,让信息技术课“美”起来
  13. 计算机毕业设计(附源码)python学科竞赛赛场安排系统
  14. Win10系统Edge可以上网其他浏览器不能上网怎么回事
  15. 暴力字典密码破解之crypt
  16. Facebook购买帐号
  17. [转]老(道)孔(儒)轮流做庄
  18. 2022年全国职业院校技能大赛(中职组)网络安全竞赛试题第十套A模块解析
  19. 几款简约而且华丽丽的桌面应用
  20. 《编译原理教程(第四版)胡元义》第二章 词法分析

热门文章

  1. 解决Word跨页表格在WPS中显示不全(转)
  2. Git 如何设置上游分支upstream?
  3. 嚼得菜根做得大事·《菜根谭》·七
  4. java实现装饰模式,JAVA实现装饰模式
  5. 新书上市 | 连载 5 年,千万读者追更,这本书讲透了通信背后的故事!
  6. 【大厂面试】面试官看了赞不绝口的Redis笔记(二)
  7. 焦点目标插件研究(wow2.4版本)
  8. 小小游戏之——英雄联盟
  9. android手机+hd图标,手机上经常出现HD小图标?手机上的HD是什么意思?这里都告诉你...
  10. MAC绕开pan限速下载的方法