59. ES6+ 封装请求
1. 前言
在学习 Promise 相关小节时我们已经了解了 Promise 的基本用法和 Promise A+规范,那么在实际项目中我们应该怎么去使用 Promise 来提高我们的效率,并且可以通过 Promise 去封装一些异步方法,让我们在使用过程中更加得心应手。
本文我们将模拟一个真实的生产环境来对前端开发中最常见也是最重要的数据请求进行封装。通过使用封装 Promise 请求来学习 Promise 在实际项目当中是如何使用的。
2. 环境搭建
工欲善其事,必先利其器,在我们进入本节的学习前,我们需要先搭建我们的开发环境,在实际的项目中也是必须的。本节使用的是 Vue 脚手架生成的项目,这里默认大家对 Vue 有了解。在 vue.config.js 配置中,对 ajax 请求进行了 mock 操作,mock 的逻辑在 mock.config.js 文件中,mock 的结果在 mock 文件夹下对应的 json。
3. 封装 ajax 请求
ajax 是前端用于发送接口请求的技术,它是异步的,需要等待结果返回后执行。
在发送 ajax 请求时,我们可能会这样去写。
ajax({
url: '',
method: '',
data: {},
params: {},
success: function (res) {},
error: function (err) {}
})
参数讲解:
url: 接口请求地址;method: 接口请求方法,如:get、post 等;data: 请求时使用 body 传输的数据,一般用于 post 请求中;params: 请求时使用 url 传递的数据,一般用于 get 请求中;success: 接口请求成功时的回调,参数为接口成功的返回值;error: 接口请求失败时的回调,参数为抛出异常时的调用栈等信息。XMLHttpRequest是浏览器提供的对象,用于进行后台与服务端的数据进行交互
3.1 实现 ajax
function ajax(options) {
const { url, method, data, params, success, error } = options;
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
// readyState 为 4 的时候已接收完毕
if (xhr.readyState === 4) {
// 状态码 200 表示成功
if (xhr.status === 200) {
console.log(xhr.responseText);
success.call(this, xhr.responseText);
} else {
console.log(xhr.status);
error.call(this, xhr.status)
}
}
};
// get 请求
if (method === 'get' || method === 'GET') {
if (typeof params === 'object') {
// params 拆解成字符串
params = Object.keys(params).map(function (key) {
return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]);
}).join('&');
}
url = params ? `${url}?${params}` : url;
xhr.open(method, url, true);
xhr.send();
}
// post 请求
if (method === 'post' || method === 'POST') {
xhr.open(method, url, true);
xhr.setRequestHeader("Content-type", "application/json; charset=utf-8");
xhr.send(JSON.stringify(params));
}
}
使用 promise 进行封装:
function ajax(url, method, params) {
return new Promise((resolve, reject) => {
// 创建 XMLHttpRequest 对象
const xhr = new XMLHttpRequest();
// 状态改变时的回调
xhr.onreadystatechange = function () {
// readyState 为 4 的时候已接收完毕
if (xhr.readyState === 4) {
// 状态码 200 表示成功
if (xhr.status === 200) {
resolve(xhr.responseText);
} else {
reject(xhr.status);
}
}
};
// ...
});
}
4. axios 库封装
在真实的项目中会经常使用到 axios 这样的 ajax 请求的库,虽然可以直接使用,但是往往业务中会有很多接口请求的地方,而这么多的请求有些固定不变的,每个接口在请求时都需要,如:token,baseURL,timeout 等等,针对这样的场景,我们可以对 axios 库进行二次业务封装。对于接口不同的返回结果我们希望有一个全局的提示框,这里我们使用 element-ui 组件库搭配使用。封装后的代码如下:
import axios from 'axios';
import { baseURL } from '@/config'
class Http {
constructor(baseUrl) {
this.baseURL = baseURL;
this.timeout = 3000;
}
setInterceptor(instance) {
instance.interceptors.request.use(config => {
return config;
});
instance.interceptors.response.use(res => {
if (res.status == 200) {
return Promise.resolve(res.data);
} else {
return Promise.reject(res);
}
}, err => {
return Promise.reject(err);
});
}
mergeOptions(options) {
return {
baseURL: this.baseURL,
timeout: this.timeout,
...options
}
}
request(options) {
const instance = axios.create();
const opts = this.mergeOptions(options);
this.setInterceptor(instance);
return instance(opts);
}
get(url, config = {}) {
return this.request({
method: 'get',
url: url,
...config
})
}
post(url, data) {
return this.request({
method: 'post',
url,
data
})
}
}
export default new Http;
5. 小结
本文我们通过真实的业务场景触发,对原生的 ajax 请求做了 promise 封装,最后我们对真实的业务场景使用 axios 对业务二次封装,这样更好地复用业务逻辑,统一增加不同返回结果的提示。
以上关于59. ES6+ 封装请求的文章就介绍到这了,更多相关内容请搜索码云笔记以前的文章或继续浏览下面的相关文章,希望大家以后多多支持码云笔记。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 admin@mybj123.com 进行投诉反馈,一经查实,立即处理!
重要:如软件存在付费、会员、充值等,均属软件开发者或所属公司行为,与本站无关,网友需自行判断
码云笔记 » 59. ES6+ 封装请求
微信
支付宝