目标
- 能够说出什么是前后端交互模式
- 能够说出Promise的相关概念和用法
- 能够使用fetch进行接口调用
- 能够使用axios进行接口调用
- 能够使用async/await方法调用接口
- 能够基于后台接口实现案例
接口调用方式
- 原生ajax
- 基于jQuery的ajax
- fetch
- axios
URL地址格式
传统形式的 URL
- 格式:Schema://host:port/path?query#fragment
- schema: 协议。例如http、https、ftp等
- host: 域名或者ip协议
- port: 端口,http默认端口80,可以省略
- path: 路径,例如/abc/a/b/c
- query: 查询路径
- fragment: 锚点(哈希Hash),用于定位页面的某个位置
Restful 形式的 URL
- HTTP请求方式
- GET 查询
- POST 添加
- PUT 修改
- DELETE 删除
异步
JavaScript的执行环境是「单线程」
- 所谓单线程,是指JS引擎中负责解释和执行JavaScript代码的线程只有一个,也就是一次只能完成一项任务,这个任务执行完后才能执行下一个,它会「阻塞」其他任务。这个任务可称为主线程
- 异步模式可以一起执行多个任务
- JS中常见的异步调用
- 定时任务
- ajax
- 事件函数
Promise 概述
Promise 是异步编程的一种解决方案,从语法上讲,Promise是一个对象,从它可以获取异步操作的消息。
使用Promise主要有以下好处:
- 可以避免多层调用嵌套问题(回调地狱)
- Promise 对象提供了简洁的API,使得控制异步操作更加容易
Promise 基本用法
- 实例化Promise对象,构造函数中传递函数,该函数中用于处理异步任务
- resolve和reject两个参数用于处理成功和失败两种情况,并通过p.then获取处理结果
var p = new Promise(function(resolve, reject) {
// 成功时调用 resolve()
// 失败时调用reject()
});
p.then(function(ret) {
// 从resolve得到正常结果
}, function (ret) {
// 从reject得到错误信息
});
Promise处理Ajax请求
1. 处理原生ajax
function queryData(url) {
let p = new Promise((resolve, reject) => {
// new一个实例对象
let xhr = new XMLHttpRequest();
// 指定回调函数,待会在这里处理响应
xhr.onreadystatechange = function() {
if(xhr.readyState != 4) return;
if(xhr.readyState == 4 && xhr.status == 200) {
// 处理正常的情况
resolve(xhr.responseText);
}else {
// 处理异常情况
reject('服务器错误');
}
};
// 准备发送前的参数
xhr.open('get', url);
xhr.send(null);
});
return p;
}
2. 按顺序处理异步请求
queryData('http://localhost:3000/data')
.then(data => {
console.log(data);
return queryData('http://localhost:3000/data1')
})
.then(data => {
console.log(data);
return queryData('http://localhost:3000/data2')
})
.then(data => {
console.log(data);
})
then参数中的函数返回值
.then(data => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(123);
}, 1000);
});
})
.then(data => {
console.log(data);
return 'hello';
})
1. 返回Promise实例对象
- 返回的该实例对象会调用下一个then
2. 返回普通值
- 返回的普通值会直接传递给下一个then,通过then参数中函数的参数接收该值(这种方式前一个then会产生一个新的Promise实例对象,使得链式操作可以继续进行)
Promise常用的api
1. 实例方法
- p.then() 得到异步任务的正确结果
- p.catch() 获取异常信息
- p.finally() 成功与否都会执行
.then(function(data) {
# 得到异步任务正确的结果
console.log(data)
})
.catch(function(data) {
# 获取异常信息
console.log(data)
})
# 成功与否都会执行(不是正式标准)
.finally(function(){
console.log('finished')
});
2. 对象方法
- Promise.all() 并发处理多个异步任务,所有任务都执行完才能得到结果
- Promise.race() 并发处理多个异步任务,只要有一个任务完成就能得到结果
Promise.all([p1,p2,p33]).then(result) => {
console.log(result)
})
Promise.race([p1,p2,p3]).then(result) => {
console.log(result);
})
接口调用-axios用法
axios 的基本特性
axios是一个基于Promise用于浏览器和node.js的HTTP客户端。
-
支持浏览器和node.js
-
支持promise
-
能拦截请求和响应
-
自动转换JSON数据
axios 基础用法
axios.get(`/adata`)
.then(ret => {
// data属性名称是固定的,用于获取后台响应的数据
console.log(ret.data)
})
axios 的常用API
- get: 查询数据
- post: 添加数据
- put: 修改数据
- delete: 删除数据
axios 传递参数
get和 delete请求传递参数
- 通过传统的url 以 ? 的形式传递参数
axios.get(`/adata?id=123`)
.then(ret => {
console.log(ret.data)
})
- restful 形式传递参数
axios.get(`/adata/123`)
.then(ret => {
console.log(ret.data)
})
app.get('/axios/:id', (req, res) => {
res.send('axios get 传递参数' + req.params.id);
})
- 通过params 形式传递参数
axios.get(`/adata`, {
params: {
id: 123
}
})
.then(ret => {
conosole.log(ret.data)
})
- post 和 put 请求传递参数
- 通过选项传递参数(默认传递的是json格式的数据)
axios.post(`/adata`, { uname: 'tom', pwd: 123 }).then(ret => { console.log(ret.data) })
- 通过 URLSearchParams 传递参数(以字符串的形式发送)
const params = new URLSearchParams(); params.append('param1', 'value1'); params.append('param2', 'value2'); axios.post('/api/test', params).then(ret => { console.log(ret.data) })
axios 的响应结果
响应结果的主要属性
- data: 实际响应回来的数据
- headers: 响应头信息
- status: 响应状态码
- statusText: 响应状态信息
axios.post('/axios-json').then(ret => {
console.log(ret)
})
axios的全局配置
axios.defaults.timeout = 3000; // 超时时间设置
axios.defaults.baseURL = 'http://localhost:300/app'; // 默认地址
axios.defaults.headers[ `mytoken` ] = 'aqwerwqwerqwer2ewrwe23eresdf23' // 设置请求头
axios拦截器
1. 请求拦截器
在请求发出之前设置一些信息
// 添加一个请求拦截器
axios.interceptors.request.use(function(config) {
// 在请求发出之前进行一些信息设置
return config;
}, function (err) {
// 处理响应的错误信息
});
2. 响应拦截器
在获取数据之前对数据做一些加工处理
axios.interceptors.response.use(function(res) {
// 在这里对返回的数据进行处理
return res;
}, function (err) {
// 处理响应的错误信息
})
接口调用-async/await用法
async/await 的基本用法
- async/await 是ES7引入的新语法,可以更加方便的进行异步操作
- async 关键字用于函数上(async函数的返回值是Promise实例对象)
- await关键字用于async函数当中(await可以得到异步的结果)
async function queryData (id) {
const ret = await axios.get('/data');
return ret;
}
queryData.then(ret => {
console.log(ret)
})
aync/await 处理多个异步请求
多个异步请求的场景
async function queryData(id) {
const info = await axios.get('/async1');
const ret = await axios.get(`async2?info=` + info.data);
return ret;
}
queryData.then(ret => {
console.log(ret);
})
基于接口的案例
- 图书相关的操作基于后台接口数据进行操作
- 需要调用接口的功能点
- 图书列表数据加载 GET http://localhost:3000/books
- 添加图书 POST http://localhost:3000/books
- 验证图书名称是否存在 GET http://localhost:3000/books/book/:name
- 编辑图书-根据ID查询图书信息 GET http://localhost:3000/books/:id
- 编辑图书-提交图书信息 PUT http://localhost:3000/books/:id
- 删除图书 DELETE http://localhost:3000/books/:id