axios 封装请求方法

一,前言

Axios 不必多介绍了。
在项目中,我们并不会直接使用 Axios,而是会对它进行一层封装。
这里提供两种不同的风格,有简单的,也有相对复杂的

二,正文

一,第一种

request.js

import axios from 'axios'

// 创建axios实例。统一配置
const service = axios.create({
    
    
  baseURL: process.env.BASE_API, // api的base_url
  timeout: 15000 // 请求超时时间
  // .... 其他信息
})

// request拦截器
service.interceptors.request.use(config => {
    
    
  //... 获取token,存储token 等操作
  return config
}, error => {
    
    
  console.log(error)
  Promise.reject(error)
})

// respone拦截器
service.interceptors.response.use(
  response => {
    
    
  	// ....
      return response.data
  },
  error => {
    
    
    // ....
    return Promise.reject(error)
  }
)

export default service

请求方法

import request from '@/utils/request'

//request() 返回的是一个 Promise
export function login(username, password) {
    
    
  return request({
    
    
    url: '/admin/login',
    method: 'post',
    //withCredentials: true, //跨域允许携带cookie
    //timeout: 30000,
    //headers: { 'Content-Type': 'application/json', 'request-ajax': true },
    data: {
    
    
      username,
      password
    }
  })

使用(也是两种使用风格)

import {
    
     login } from '@/api/login'

confirm(){
    
    
	login(this.loginForm).then(response => {
    
    
		//...
	}).catch( error => {
    
    
		//...
	})
}

//使用async await 语法糖
async confirm(){
    
    
	try{
    
    
		const response = await login(this.loginForm)
		// ...
	}catch(error){
    
    
		// ....
	}
}

二,第二种

request.js

import axios from 'axios'

//响应拦截器
axios.interceptors.response.use(
	function(response) {
    
    
		//....
		return response
	},
	function(error) {
    
    
		return Promise.reject(error)
	}
)

//请求拦截器 
axios.interceptors.request.use(
	function(config) {
    
    
		//...
		return config
	},
	function(error) {
    
    
		return Promise.reject(error)
	}
)


/*
 * 封装请求方法
 */
const request = function(query) {
    
    
	return axios
		.request(query)
		.then((res) => {
    
    
			//...
			if (res.data.code === 401) {
    
    
				  vue.prototype.$$router.push({
    
     path: '/login' })
				return Promise.reject(res.data)
			} else if (res.data.code === 500) {
    
    
				return Promise.reject(res.data)
			} else if (res.data.code === 501) {
    
    
				return Promise.reject(res.data)
			} else if (res.data.code === 502) {
    
    
				  vue.prototype.$$router.push({
    
     path: '/login' })
				return Promise.reject(res.data)
			} else {
    
    
				return Promise.resolve(res.data)
			}
		})
		//对错误进行处理
		.catch((e) => {
    
    
			return Promise.reject(e.message)
		})
}

//post请求  ----> json格式的post请求 
const post = function(url, params) {
    
    
	const query = {
    
    
		url: url,
		method: 'post',
		withCredentials: true, //跨域允许携带cookie
		timeout: 30000,
		data: params,
		headers: {
    
     'Content-Type': 'application/json', 'request-ajax': true },
	}
	return request(query)
}

//Get请求
const get = function(url, params) {
    
    
	const query = {
    
    
		url: url,
		method: 'get',
		withCredentials: true,
		timeout: 30000,
		params: params,
		headers: {
    
     'request-ajax': true },
	}
	return request(query)
}

//post请求
const form = function(url, params) {
    
    
	const query = {
    
    
		url: url,
		method: 'post',
		withCredentials: true,
		timeout: 30000,
		data: params,
		headers: {
    
    
			'Content-Type': 'multipart/form-data',
			'request-ajax': true,
		},
	}
	return request(query)
}

请求方法

import {
    
     post } from '@/util/request'



//默认导出的是一个对象
export default {
    
    
  login: query => post(`/api/login`, query), 
  logout: query => post(`/api/logout`, query)
}

在 vue.config.js 配置一下代理

module.exports = {
    
    
	devServer: {
    
    
		open: true,
		host: 'localhost',
		port: 8001,
		https: false,
		hotOnly: false,
		proxy: {
    
    
			'/api': {
    
    
				target: 'http://localhost:8000',
				changeOrigin: true,
			},
		},
	},
}

使用

import loginApi from '@/api/login'

handleLogin() {
    
    
	loginApi
	.login(this.loginForm)
	.then((result) => {
    
    })
	//其实一般不捕获这个异常 要结合后端返回数据的情况
	.catch((error) => console.log(error))

//使用async await 语法糖
async handleLogin(){
    
    
	try{
    
    
		const response = await loginApi.login(this.loginForm)
		// ...
	}catch(error){
    
    
		//其实一般不捕获这个异常。要结合后端返回数据的情况
		// ....
	}
}

其实这两种风格大同小异,主要是想利用这个来更加熟悉 Promise

三,Promise

1,简介

Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理且更强大。它最早由社区提出并实现,ES6将其写进了语言标准,统一了用法,并原生提供了Promise对象。

JS 基础:JS异步任务会在异步任务队列中,只有执行完主任务(主进程),才会不断轮询异步任务队列然后执行队列中的方法。JS异步任务有:文件的加载,定时器,表单请求,ajax请求…

2,Promise的三种状态

  • Pending状态(进行中)
  • Fulfilled状态(已成功)
  • Rejected状态(已失败

Promise 的状态一旦发生改变就不再变化,不可逆(两种状态改变:成功或失败)

  • Pending -> Fulfilled
  • Pending -> Rejected

3,语法

(1) 进行阶段
console.log(new Promise((resolve,reject) => {
    
    }))  //pending
(2) 如何改变状态

Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由JavaScript引擎提供,不用自己部署。

resolve作用是将Promise对象状态由“未完成”变为“成功”,也就是Pending -> Fulfilled,在异步操作成功时调用,并将异步操作的结果作为参数传递出去;而reject函数则是将Promise对象状态由“未完成”变为“失败”,也就是Pending -> Rejected,在异步操作失败时调用,并将异步操作的结果作为参数传递出去。

//成功后用resolve方法来通知(改变Promise的状态)
new Promise((resolve,reject) => {
    
    
    resolve("成功状态")
})
new Promise((resolve,reject) => {
    
    
    reject("拒绝状态")
})
(3) 状态改变后的回调

then:Promise实例生成后,可用then方法分别指定两种状态回调参数。then 方法可以接受两个回调函数作为参数:

  • Promise对象状态改为Resolved时调用 (必选)
  • Promise对象状态改为Rejected时调用 (可选)
new Promise((resolve,reject) => {
    
    
    // reject("拒绝状态") //失败的  ---> (干活的)
    resolve("成功状态") //成功的    ---> (干活的)
}).then(value => {
    
    
    console.log(value) //成功会执行这个  ---> (干完活对数据的处理)  --- value 是 resolve传过来的数据
},reason => {
    
    
    console.log(reason) //失败会执行这个 ---> (干完活对数据的处理)  --- reason 是 reject传过来的数据
})

//成功状态

提示:

  • 如果没有改变Promise的状态,then就永远无法执行
  • 每个then返回的也是一个Promise,而且默认是返回成功的结果
new Promise( (resolve,reject) => {
    
    
	resolve()
})
.then(msg => {
    
    },error => {
    
    })
.then(msg => {
    
    },error => {
    
    })
//其实就等价于:
new Promise( (resolve,reject) => {
    
    
	resolve()
})
.then( () => {
    
    
	return new Promise( (resolve,reject) => {
    
    
		resolve()
	})
})
.then(msg => {
    
    },error => {
    
    })
  • 如果then里面有返回值,那么下一个then的参数就是返回值内容(即在下一个then就能接收到)
let p1 = new Promise((resolve,reject) => {
    
    
    resolve("resolve")
})
.then(
    value => {
    
    return "返回值"},
    reason => {
    
     console.log(reason) })
.then(
    value => {
    
    console.log(value)} //结果:返回值,
    reason => {
    
     console.log(reason) })
  • 如果返回的对象中有一个 then方法,那么会被封装为Promise
let p1 = new Promise((resolve,reject) => {
    
    
    resolve("resolve")
})
.then(
    value => {
    
    
        return {
    
    
        	then((resolve,reject) => {
    
    
        		resolve("resolve")
    	})
	}}, 
    reason => {
    
     console.log(reason) })
  • 一般是这样使用的。不是直接使用Promise,而是封装成一个函数,需要的时候调用
function request(){
    
    
    return new Promise((resolve,reject) => {
    
    
        //异步调用,请求后端接口
		resolve(data)
    })
}

request().then(value => {
    
    
    console.log(value)
})
(4)执行顺序
let promise = new Promise(function(resolve, reject){
    
    
    console.log("AAA");
    resolve()
});
promise.then(() => console.log("BBB"));
console.log("CCC")

// AAA
// CCC
// BBB

执行后,我们发现输出顺序总是 AAA -> CCC -> BBB。表明,在Promise新建后会立即执行,所以首先输出 AAA。然后,then方法指定的回调函数将在当前脚本所有同步任务执行完后才会执行,所以BBB 最后输出。

(5)Promise多种错误检测与catch使用
let p1 = new Promise((resolve,reject) => {
    
    
    reject("resolve")  //这样会进入reject
    throw new Error() //这样也会进入reject
    hd + 1 //hd变量没定义,报错,也会进入reject
})
.then(
    value => {
    
     console.log(value) }, 
    reason => {
    
     console.log(reason) })
//可以使用catch捕获,对错误统一进行处理
let p1 = new Promise((resolve,reject) => {
    
    
    reject("resolve")  //这样会进入reject
    throw new Error() //这样也会进入reject
    hd + 1 //hd变量没定义,报错,也会进入reject
})
.then( value => {
    
     console.log(value) })
.then( value => {
    
     console.log(value) })
.then( value => {
    
     console.log(value) },reason => {
    
     console.log(reason) })
.catch( reason => {
    
    
    console.log(reason) //一般习惯放在最后,对所有Promise统一处理
})
let p1 = new Promise((resolve,reject) => {
    
    
    reject("resolve")  //这样会进入reject
    throw new Error() //这样也会进入reject
    hd + 1 //hd变量没定义,报错,也会进入reject
})
.then( value => {
    
     console.log(value) },reason => {
    
     console.log(reason) })
.catch( reason => {
    
    
    console.log(reason) //一般习惯放在最后,对所有Promise统一处理
})
.finally(() => {
    
    
    console.log("始终会执行")
})
(6)Promise.all 批量获取数据
const p1 = new Promise((resolve,reject) => {
    
    
    resolve("第一个异步")
})

const p2 = new Promise((resolve,reject) => {
    
    
    resolve("第二个异步")
})

Promise.all([p1,p2]).then(result => {
    
    
    console.log("all") //全部成功才是成功
})
.catch(() => {
    
    
    console.log("error")  //catch也是返回一个Promise,状态也是成功
})
(7)Promise 语法糖:async await

async

顾名思义,异步。async函数对 Generator 函数的改进,async 函数必定返回 Promise(async就类似于 Promise,而且是成功的状态),我们把所有返回 Promise 的函数都可以认为是异步函数。特点体现在以下四点:

  • 内置执行器
  • 更好的语义
  • 更广的适用性
  • 返回值是 Promise

await

顾名思义,等待。正常情况下,await命令后面是一个 Promise 对象,返回该对象的结果。如果不是 Promise 对象,就直接返回对应的值。另一种情况是,await命令后面是一个thenable对象(即定义then方法的对象),那么await会将其等同于 Promise 对象。

function sleep(ms) {
    
    
    return new Promise(function(resolve, reject) {
    
    
        setTimeout(resolve,ms);
    })
}
async function handle(){
    
    
    console.log("AAA")
    await sleep(5000)
    console.log("BBB")
}

handle();
//handle().then( msg => {},error => {} )
// AAA
// BBB (5000ms后)

我们定义函数sleep,返回一个Promise。然后在handle函数前加上async关键词,这样就定义了一个async函数。在该函数中,利用await来等待一个Promise。

(8)async await 语法糖的错误处理
async function hd(){
    
    
    console.log(name)
}

hd().catch( error => console.log(error) )

//标准
async function hd(){
    
    
    try{
    
    
        let data = await ajax()
    }catch(error){
    
    
        
    }
}

猜你喜欢

转载自blog.csdn.net/saienenen/article/details/115030205