执行 POST 请求:
axios.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
.then(function (response) {
console.log(response);
.catch(function (error) {
console.log(error);
});
执行多个并发请求
function getUserAccount() {
return axios.get('/user/12345');
function getUserPermissions() {
return axios.get('/user/12345/permissions');
axios.all([getUserAccount(), getUserPermissions()])
.then(axios.spread(function (acct, perms) {
// 两个请求现在都执行完成
}));
注意:
axios.all就是给Promise.all方法换了个名字而已,axios.all方法就是对Promise.all方法进行了一层包装,本质上是一模一样的。
2、axios API
可以通过向 axios 传递相关配置来创建请求
// 发送 POST 请求
axios({
method: 'post',
url: '/user/12345',
data: {
firstName: 'Fred',
lastName: 'Flintstone'
});
// 获取远端图片
axios({
method:'get',
url:'http://bit.ly/2mTM3nY',
responseType:'stream'
.then(function(response) {
response.data.pipe(fs.createWriteStream('ada_lovelace.jpg'))
});
3、请求方法的别名
为方便起见,为所有支持的请求方法提供了别名
axios.request(config)
axios.get(url[, config])
axios.delete(url[, config])
axios.head(url[, config])
axios.options(url[, config])
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])
axios.patch(url[, data[, config]]
axios.request(config):
axios({
method: 'post',
url: '/user/12345',
data: {
firstName: 'Fred',
lastName: 'Flintstone'
timeout: 1000,
...//其他相关配置
});
axios.get(url[, config])
axios.get('demo/url', {
params: {
id: 123,
name: 'Henry',
timeout: 1000,
...//其他相关配置
// `url` 是用于请求的服务器 URL
url: '/user',
// `method` 是创建请求时使用的方法
method: 'get', // 默认是 get
// `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。
// 它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL
baseURL: 'https://some-domain.com/api/',
// `transformRequest` 允许在向服务器发送前,修改请求数据
// 只能用在 'PUT', 'POST' 和 'PATCH' 这几个请求方法
// 后面数组中的函数必须返回一个字符串,或 ArrayBuffer,或 Stream
transformRequest: [function (data) {
// 对 data 进行任意转换处理
return
data;
}],
// `transformResponse` 在传递给 then/catch 前,允许修改响应数据
transformResponse: [function (data) {
// 对 data 进行任意转换处理
return data;
}],
// `headers` 是即将被发送的自定义请求头
headers: {'X-Requested-With': 'XMLHttpRequest'},
// `params` 是即将与请求一起发送的 URL 参数
// 必须是一个无格式对象(plain object)或 URLSearchParams 对象
params: {
ID: 12345
// `paramsSerializer` 是一个负责 `params` 序列化的函数
// (e.g. https://www.npmjs.com/package/qs, http://api.jquery.com/jquery.param/)
paramsSerializer: function(params) {
return Qs.stringify(params, {arrayFormat: 'brackets'})
// `data` 是作为请求主体被发送的数据
// 只适用于这些请求方法 'PUT', 'POST', 和 'PATCH'
// 在没有设置 `transformRequest` 时,必须是以下类型之一:
// - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
// - 浏览器专属:FormData, File, Blob
// - Node 专属: Stream
data: {
firstName: 'Fred'
// `timeout` 指定请求超时的毫秒数(0 表示无超时时间)
// 如果请求话费了超过 `timeout` 的时间,请求将被中断
timeout: 1000,
// `withCredentials` 表示跨域请求时是否需要使用凭证
withCredentials: false, // 默认的
// `adapter` 允许自定义处理请求,以使测试更轻松
// 返回一个 promise 并应用一个有效的响应 (查阅 [response docs](#response-api)).
adapter: function (config) {
/* ... */
// `auth` 表示应该使用 HTTP 基础验证,并提供凭据
// 这将设置一个 `Authorization` 头,覆写掉现有的任意使用 `headers` 设置的自定义 `Authorization`头
auth: {
username: 'janedoe',
password: 's00pers3cret'
// `responseType` 表示服务器响应的数据类型,可以是 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'
responseType: 'json', // 默认的
// `xsrfCookieName` 是用作 xsrf token 的值的cookie的名称
xsrfCookieName: 'XSRF-TOKEN', // default
// `xsrfHeaderName` 是承载 xsrf token 的值的 HTTP 头的名称
xsrfHeaderName: 'X-XSRF-TOKEN', // 默认的
// `onUploadProgress` 允许为上传处理进度事件
onUploadProgress: function (progressEvent) {
// 对原生进度事件的处理
// `onDownloadProgress` 允许为下载处理进度事件
onDownloadProgress: function (progressEvent) {
// 对原生进度事件的处理
// `maxContentLength` 定义允许的响应内容的最大尺寸
maxContentLength: 2000,
// `validateStatus` 定义对于给定的HTTP 响应状态码是 resolve 或 reject promise 。如果 `validateStatus` 返回 `true` (或者设置为 `null` 或 `undefined`),promise 将被 resolve; 否则,promise 将被 rejecte
validateStatus: function (status) {
return status >= 200 && status < 300; // 默认的
// `maxRedirects` 定义在 node.js 中 follow 的最大重定向数目
// 如果设置为0,将不会 follow 任何重定向
maxRedirects: 5, // 默认的
// `httpAgent` 和 `httpsAgent` 分别在 node.js 中用于定义在执行 http 和 https 时使用的自定义代理。允许像这样配置选项:
// `keepAlive` 默认没有启用
httpAgent: new http.Agent({ keepAlive: true }),
httpsAgent: new https.Agent({ keepAlive: true }),
// 'proxy' 定义代理服务器的主机名称和端口
// `auth` 表示 HTTP 基础验证应当用于连接代理,并提供凭据
// 这将会设置一个 `Proxy-Authorization` 头,覆写掉已有的通过使用 `header` 设置的自定义 `Proxy-Authorization` 头。
proxy: {
host: '127.0.0.1',
port: 9000,
auth: : {
username: 'mikeymike',
password: 'rapunz3l'
// `cancelToken` 指定用于取消请求的 cancel token
// (查看后面的 Cancellation 这节了解更多)
cancelToken: new CancelToken(function (cancel) {
响应结构:
// `data` 由服务器提供的响应
data: {},
// `status` 来自服务器响应的 HTTP 状态码
status: 200,
// `statusText` 来自服务器响应的 HTTP 状态信息
statusText: 'OK',
// `headers` 服务器响应的头
headers: {},
// `config` 是为请求提供的配置信息
config: {}
处理并发请求的助手函数
axios.all(iterable)
axios.spread(callback)
5、创建实例
可以使用自定义配置新建一个 axios 实例
axios.create([config])
const instance = axios.create({
baseURL: 'https://some-domain.com/api/',
timeout: 1000,
headers: {'X-Custom-Header': 'foobar'}
});
6、实例方法
以下是可用的实例方法。指定的配置将与实例的配置合并。
axios#request(config)
axios#get(url[, config])
axios#delete(url[, config])
axios#head(url[, config])
axios#options(url[, config])
axios#post(url[, data[, config]])
axios#put(url[, data[, config]])
axios#patch(url[, data[, config]])
7、在Vue项目中进行全局配置

具体配置项参考官方文档:
http://axios-js.com/zh-cn/docs/
添加配置项axios/index.js
// 1. 引入
import axios from "axios";
// 2. 创建实例
const instance = axios.create(
config)
// 3. 配置信息
let config = {
// 每次请求的协议、IP地址。 设置该配置后,每次请求路径都可以使用相对路径,例如"/admin/login"
baseURL: "http://localhost",
// 请求超时时间
timeout: 10000,
// 每次请求携带cookie
withCredentials: true
// 4. 导出
export default instance
引入配置实例
在main.js中引入刚才进行配置的axios实例
import ...
// 1. 引入实例
import axios from './axios'
// 因为 axios 文件夹下只创建了一个 index.js 文件,那么 webpack 会默认把该文件打包,所以这里的路径可以不用加上 '/index.js'
// 2. 与Vue实例关联
Vue.prototype.$axios = axios
new Vue({
在组件中使用
<script>
export default {
methods: {
handleClick(){
this.$axios.post("/getList", {pid: 157})
.then(res => console.log(res))
.catch(err => console.log(err))
</script>
二、ES6 Promise 对象
Promise 是一个对象,从它可以获取异步操作的消息。Promise 异步操作有三种状态:pending(进行中)、fulfilled(已成功)和 rejected(已失败)。
1、then 方法
then 方法接收两个函数作为参数,第一个参数是 Promise 执行成功时的回调,第二个参数是 Promise 执行失败时的回调,两个函数只会有一个被调用。
const p = new Promise(function(resolve,reject){
resolve('success');
});
p.then(function(value){
console.log(value);
});
then 方法将返回一个 resolved 或 rejected 状态的 Promise 对象用于链式调用,且 Promise 对象的值就是这个返回值。
const p = new Promise(function(resolve,reject){
resolve(1);
}).then(function(value){ // 第一个then // 1
console.log(value);
return value * 2;
}).then(function(value){ // 第二个then // 2
console.log(value);
}).then(function(value){ // 第三个then // undefined
console.log(value);
return Promise.resolve('resolve');
}).then(function(value){ // 第四个then // resolve
console.log(value);
return Promise.reject('reject');
}).then(function(value){ // 第五个then //reject:reject
console.log('resolve:' + value);
}, function(err) {
console.log('reject:' + err);
});
大多数浏览器中不能终止的 Promise 链里的 rejection,建议后面都跟上 .catch(error => console.log(error));
const p = new Promise(function(resolve,reject){
resolve(1);
}).then(function(value){ // 第一个then // 1
console.log(value);
return value * 2;
}).catch(error => console.log(error));
三、async和await
async它作为一个关键字放到函数前面,用于表示函数是一个异步函数,也就意味着该函数的执行不会阻塞后面代码的执行。
await后面接一个会return new promise的函数并执行它,await只能放在async函数里。
function getRandom(){
return new Promise((resolve, reject)=>{
let sino = parseInt(Math.random() * 6 +1)
setTimeout(()=>{
resolve(sino)
},3000)
async function test(){
let n =await getRandom()
console.log(n)
test()
async中await getRandom()先执行,等到三秒后再把得到的结果赋值给左边的n,所以test函数是异步的,因此前面必须写async。
有多个promise,怎么拿到所有的promise都结束后的结果:
function getRandom(猜测){
return new Promise((resolve, reject)=>{
let sino = parseInt(Math.random() * 6 +1)
if(sino > 3){
if(猜测 === '大')
{
resolve(sino)
}else{
console.log('error')
reject(sino)
}else{
if(猜测 === '大'){
console.log('error')
reject(sino)
}else{
resolve(sino)
setTimeout(()=>{
resolve(sino)
},300)
Promise.all([getRandom('大'),getRandom('大')]).then((x)=>{console.log(x)},(y)=>{console.log(y)})
promise.all参数是一个数组,数组的每一项是一个返回promise的函数调用,then的第一个参数是所有的promise都成功后调用,拿到所有promise的结果是一个数组;第二个参数拿到的是第一个失败的值。
async 函数返回的是一个promise 对象,如果要获取到promise 返回值,应该用then 方法。
async function timeout() {
return 'hello world'
timeout().then(result => {
console.log(result);
console.log('虽然在后面,但是我先执行');
虽然在后面,但是我先执行
hello world
注意:
如果没有在async函数中写return,那么Promise对象resolve的值就是是undefined。
await 返回的结果,如果不是 promise对象 , await会阻塞后面的代码,先执行async方法外的同步代码,同步代码执行完,再回到async方法,把这个非promise的返回值,作为 await表达式的结果。
如果它等到的是一个 promise 对象,await 也会暂停async方法内后面的代码,先执行async方法外的同步代码,等着 Promise 对象 fulfilled,然后把 resolve 的参数作为 await 表达式的运算结果。
function fn(){
return new Promise(resolve=>{
console.log(1)
async function f1(){
await fn()
console.log(2)
f1()
console.log(3)
因为没有resolve结果,所以await拿不到值,因此不会打印2
function fn(){
return new Promise(resolve=>{
console.log(1)
resolve()
async function f1(){
await fn()
console.log(2)
f1()
console.log(3)
四、nextTick
nextTick:在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。
Vue 实现响应式并不是数据发生变化之后 DOM 立即变化,而是按一定的策略进行 DOM 的更新。简单来说,Vue在修改数据后,视图不会立刻更新,而是等同一事件循环中的所有数据变化完成之后,再统一进行视图更新。
<template>
<div class="hello">
<button id="firstBtn" @click="testClick()" ref="aa">{{testMsg}}</button>
</div>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data () {
return {
testMsg:"原始值",
methods:{
testClick:function(){
let that=this;
that.testMsg="修改后的值";
console.log(that.$refs.aa.innerText);
//that.$refs.aa获取指定DOM,输出:原始值
</script>
使用 Vue.nextTick(callback) :
methods:{
testClick:function(){
let that=this;
that.testMsg="修改后的值";
that.$nextTick(function(){
console.log(that.$refs.aa.innerText);
//输出:修改后的值
});
Vue.nextTick()使用场景:
- 在Vue生命周期的created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中。原因是在created()钩子函数执行的时候DOM其实并未进行任何渲染,而此时进行DOM操作无异于徒劳,所以此处一定要将DOM操作的js代码放进Vue.nextTick()的回调函数中。与之对应的就是mounted钩子函数,因为该钩子函数执行时所有的DOM挂载和渲染都已完成,此时在该钩子函数中进行任何DOM操作都不会有问题。
- 在数据变化后要执行的某个操作,当你设置 vm.someData = ‘new
value’,DOM并不会马上更新,而是在异步队列被清除,也就是下一个事件循环开始时执行更新时才会进行必要的DOM更新。如果此时你想要根据更新的DOM 状态去做某些事情,就会出现问题。为了在数据变化之后等待 Vue 完成更新 DOM ,可以在数据变化之后立即使用Vue.nextTick(callback) 。这样回调函数在 DOM 更新完成后就会调用。 - mounted 不会承诺所有的子组件都一起被挂载。如果你希望等到整个视图都渲染完毕,可以用 vm.$nextTick 替换掉mounted
参考博客:
https://blog.csdn.net/weixin_33608494/article/details/112267088
https://blog.csdn.net/zhouzuoluo/article/details/84752280
es6 的promise 逐步解决了层层回调的问题,es8的async await让异步变成了同步的写法,在vue中,可以通过封装axios,使得所有的请求都可以使用同步写法,同时处理错误信息等,可以建一个api.js文件,全局创建api实例.
import axios from 'axios'
const qs = require('qs')
const api = {
async get (url, data) {
try {
let res = await axios.get(url, {params: data})
res = res.data
return
最近写练习项目的时候,用到了echart,官方推荐的是在mounted下进行表格配置,然而很多时候数据都是来源于异步ajax,问题来了,在这里尝试使用create下获取的异步的data数据,结果报错说undefined,这里提前在data下声明过变量名,哪怕在定义created时声明了async使用await阻塞,依旧无法获取。
查询之后发现说这个东西是,vue生命周期函数之间不会被阻塞,后一个生命周期不一定会等前一个完全执行完再执行,目前在csdn下搜到的解决方案主要有
1、在mounted下使用定时
vue 生命周期函数加上了async之后,父子组件的各自生命周期函数的执行顺序发生了变化:
父组件created未加async之前:
父created -> 子created -> 子mounted -> 父mounted
父组件created加上async之后:
父created未执行完 -> 子created -> 子mounted -> 父created执行完 -> 父mounted
在我的认知中,async/await会等待await返回,那么必然就是同步的,既然是同步的,那么就是会阻塞事件循环。
刚好有个同事问了一个接口并发的问题,看了一下代码,我看见有使用async/await,于是信誓旦旦的说会阻塞,结果打脸了,结果是并不会,看下面代码:
async function fn1(){
console.log(1);
await pr1();
await pr2();
console.log(2);
function fn2(){
console.log(
npm init -y
npm i gulp -g (使用命令 gulp)
npm i gulp -D #npm i gulp@3.9.1 --save-dev 开发依赖(前端工具都是开发依赖 本地安装 代码加载模块)
npm i axios -S #npm i axios --save 项目依赖-线上项目依赖(线上的代码需要用到 比如 axios)
async/await是ES20717引入的,主要是简化Promise调用操作,实现了以异步操作像同步的方式去执行,async外部是异步执行的,同步是await的作用。
async 和 await 用于异步(promise)处理。
async 和await 不能用于生命周期(beforeCreate( 创建前 ,created ( 创建后 ),beforeMount(挂载组件之前)mounted(挂载完组件)beforeUpdate(更新之前),updated(更新后)beforeDestroy(销毁前),destroyed(销毁后))。
为什么?生命周期是同步,async和await是异步,它会让同步变成异步。
await 后面接收返回的new Promise 函数并执
当在node.js函数中使用async / await时,它是否会阻塞node.js线程,直到它执行下一行代码?
1、async或await不会阻止整个解释器,node.js仍然将所有JavaScript作为单线程运行,即使某些代码再async或await上等待,其他事件仍然可以继续运行其事件处理程序(node.js不会被阻止)。
2、 事件队列仍在为其他事件提供服务,是一个事件,解决了一个允许
从逻辑上讲,您可以考虑在执行函数时遇到await关键字时node.js执行的操作如下:
进行函数调用