异步编程
回调函数是一种基于事件的,自动调用的函数
回调函数其他的代码不会等待回调函数执行完毕
promise
Promise是异步编程的一种解决方案,所谓Promise简单来说是一个容器,里面保存着某个未来才会结束的事件,(通常是一个异步操作)的结果。
从语法上说,Promise是一个对象,从它可以获取异步操作的消息。Promise提供统一等待API,各种异步操作都可以用同样的方法进行处理
- Promise对象的特点
- Promise对象代表一个异步操作,由三种状态:‘Pending’(进行中)、‘Resolved’(已完成)和’Rejected’(已失败)。只有异步操作的结果可以确定当前是哪一种状态,其他任何操作都无法改变这个状态
- 一旦状态改变就不会再变,任何时候都可以得到这个结果,Promise对象的状态改变只有两种可能:从Pending到Resolved和从Pending到Rejected
<template>
<div>
<button @click="fetchData">Fetch Data</button>
<p v-if="data">{{ data }}</p>
</div>
</template>
<script>
export default {
data() {
return {
data: null
};
},
methods: {
fetchData() {
// 使用Promise处理异步操作
//resolve是处理成功的函数,reject是处理失败的函数
//在回调函数中如果调用了resolve/reject方法promise就会由pending转换为resolved/reject状态
new Promise((resolve, reject) => {
// 模拟异步操作
setTimeout(() => {
resolve('Data fetched!');
}, 2000);
//获取回调函数结果,then、catch会等待promise中的运行结果,但是不会阻塞代码继续运行
}).then((result) => {
//等待promise对象状态为resolve时才会执行的代码
this.data = result;
}).catch((error) => {
//当promise状态为reject或者promise出现异常时会执行的函数
console.error(error);
});
}
}
};
</script>
async使用简洁语法获得promise对象
async标识的函数就是一个回调函数,所返回的结果就是一个promise
方法如果正常return结果,promise状态就是resolved return后的结果就是成功状态的返回值
方法中出现了异常,则返回的promise就是一个失败状态
async函数返回的结果如果是一个promise,则状态由内部的promise决定
await 帮助我们获取promise成功状态的返回值的关键字
await右边如果是一个普通值,则直接返回该值,如果右边是promise,返回promise成功状态的结果
await右边如果是一个失败状态的promise,那么await会直接抛异常
await关键字必须在async修饰的函数中使用,async函数中可以没有await
await后边的代码会等待await执行完毕继续执行
// 创建一个返回Promise对象的函数
function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Data fetched successfully!');
}, 2000);
});
}
// 使用async函数获取Promise对象的结果
async function getData() {
try {
//使用await函数来获取执行成功的值
const result = await fetchData();
console.log(result);
} catch (error) {
//当await关键字右边返回失败状态函数时会直接抛出异常
console.log('An error occurred: ', error);
}
}
// 调用getData函数
getData();
axios
axios返回的是一个promise对象,特性见上小节
axios其实底层上依旧是对XMLHttpRequest的一个封装
使用npm安装axios:
npm install axios
const axios = require('axios');
// 发起GET请求
//如果请求方式为get,则data中的数据会以键值对形式放在url后
//如果请求方式为post,则data中的数据会以JSON方式放入请求体
/*
发送get请求的方法
axios.get(url)
axios.get(url,{请求的其他信息})
axios.get(url,{params:{键值对参数},header:{设置一些特殊的请求头}})
发送post请求的方法
axios.post(url,{要放入请求体的json串},{请求的其他信息})
*/
axios.get('https://jsonplaceholder.typicode.com/posts')
//response 响应结果对象
//data服务端响应回来的数据
//status响应状态码
.then(response => {
//promise为成功状态时获取执行成功的值
console.log(response.data);
})
.catch(error => {
//promise状态为失败的处理
console.error(error);
});
请求和响应拦截器
若在axios发送请求之前,或者是数据响应回来再执行then方法之前做一些额外的工作,跨域通过拦截器完成
import axios from 'axios';
// 创建一个 Axios 实例
const instance = axios.create({
baseURL: 'https://api.example.com/'
});
// 请求拦截器
instance.interceptors.request.use(
config => {
// 在请求被发送之前做一些处理
// 比如在请求头中加入 token
config.headers.Authorization = `Bearer ${localStorage.getItem('token')}`;
return config;
},
error => {
// 对请求错误做些什么
return Promise.reject(error);
}
);
// 响应拦截器
instance.interceptors.response.use(
response => {
// 对响应数据做些什么
return response;
},
error => {
// 对响应错误做些什么
if (error.response.status === 401) {
// 处理未授权的情况
}
return Promise.reject(error);
}
);
// 发送请求
instance.get('/users')
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error(error);
});