axios的官网

axios的post默认用法(异步)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
const axios = require('axios'); //引入 "axios" 模块 ,终端中执行: npm install axios

//设置请求头
let headers = {
'Host': 'gw-xeasy.xsdsd.cn',
'Connection': 'keep-alive',
'sec-ch-ua': '"Not)A;Brand";v="99", "Google Chrome";v="127", "Chromium";v="127"',
'Accept': 'application/json, text/plain, */*',
'Cookie': User.Cookie,
};

//设置网址 url 和请求的数据 data
const url = 'https://gw-xeasy.com/page';
const data = { "businessType": 3, "pageSize": 10, "pageNum": 1};

function 发送请求()
{
//开始发送请求post
axios.post(url, data, { headers: headers })
.then(response => {
console.log('查询的结果:', response.data); //直接展示结果
console.log('查询的结果:', JSON.stringify(response.data, null, 2));//将结果转化为 JSON 数据
return response.data; //请注意!return 的数据不会传递到外部,因为 axios.post 是异步操作。
//要想得到返回值,可以使用 Promise 或 async/await
})
.catch(error => {
console.error('发生错误:', error.response ? error.response.data : error.message);
});
}

axios的post “同步”请求

方法一 使用async与await 【推荐使用】

关于 async 的详细使用方法,见后面的章节《异步函数 async》。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const axios = require('axios');

let headers = {
'Host': 'gw-xeasy.xasdasd.cn',
'Connection': 'keep-alive',
};

const idList = await getPaperAnalyze();
console.log('idList:', idList);
//getPaperAnalyze 使用 async/await 来返回数据。
//将 getPaperAnalyze 修改为 async 函数并使用 await 获取结果,从而能直接在主流程中得到 idList:

async function getPaperAnalyze() {
const url = 'https://gw-xeasy.asdasd.cn/analyze/task/query/page';
const data = { "businessType": 3, "pageSize": 10, "pageNum": 1,};

try {
const response = await axios.post(url, data, { headers: headers });//开始发送post请求
return response.data.data.resultList; // 返回 ID 列表
}
catch (error) {
console.error('发生错误:', error.response ? error.response.data : error.message);
throw error; // 重新抛出错误,方便调用处捕获
}
}

方法二 使用promise与.then

axios.post 方法返回一个 Promise 对象。这意味着 axios.post 调用是异步执行的,它立即返回一个 Promise,而不是等待HTTP请求完成。

可以使用 .then() 方法来添加一个处理函数,这个函数会在 Promise 被成功解决(即HTTP请求成功返回)时被调用。如果请求失败,则会调用 .catch() 方法中定义的错误处理函数。

下面这个例子中,queryPaper函数会返回一个paperList的数组对象回来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 使用 queryPaper 函数并处理返回的 Promise
queryPaper().then(paperList => {
console.log('查询到' + paperList.length + '份试卷,请选择要分发的试卷:');
// 这里可以继续处理 paperList

});

//这里是试卷查询,最后会返回一个数组对象,每个对象中有试卷的id与title
function queryPaper() {
console.log('正在查询试卷,请稍等...');
// 定义请求体
let data = {"year": "2024", "grade": "166", };

// 发送 POST 请求
return axios.post('https://gw-xeasy.xsdsd.cn/xeasy-srv-item/paper/search', data, { headers: headers })
.then(response => {
let paperList = response.data.data.records;
console.log(JSON.stringify(paperList, ['title', 'paperId'], 4));
return paperList;
})
.catch(error => {
console.error('Error:', error.response ? error.response.data : error.message);
});
}

请求头的注意事项

数据长度 Content-Length

有时候数据长度不对会导致请求失败。可以使用下面的语句在data数据准备完成之后,进行动态计算。

1
headers['Content-Length'] = Buffer.byteLength(JSON.stringify(data)); // 动态计算

响应结果

将响应结果进行JSON格式化输出

1
2
3
JSON.stringify(response.data, 过滤方法, 缩进的空格数)); //response.data 是响应的结果

JSON.stringify(response.data, null, 4)); //格式化 response.data ,不用过滤方法,使用4个空格进行缩进。

过滤方法——使用举例

这个过滤方法,可以是一个函数,也可以是一个数组。

下面给出使用数组作为过滤方法,提取对象中的某些属性。

1
2
3
4
5
6
7
8
9
let a = [
{"name":"王多鱼","sex":"male","age":18},
{"name":"蔡徐坤","sex":"male","age":28},
{"name":"马保国","sex":"male","age":58},
]

//定义过滤方法,过滤出的结果只包含“name”、“age”
let replace =["name","age"];
console.log(JSON.stringify(a,replace,4));

输出结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[
{
"name": "王多鱼",
"age": 18
},
{
"name": "蔡徐坤",
"age": 28
},
{
"name": "马保国",
"age": 58
}
]

JS 异步编程和事件循环

JavaScript是一种单线程语言,它使用事件循环来处理异步操作。这意味着JavaScript可以在不阻塞主线程的情况下执行异步任务,例如网络请求、定时器等。

异步操作的两种主要方式

  1. Promise 和 .then()/.catch()

    • Promise 是一种用于异步编程的对象,它代表了一个未来将要完成或失败的操作。
    • 使用 .then().catch() 方法来处理 Promise 的成功和失败状态。
  2. async/await

    • async 关键字用于声明一个函数是异步的,这意味着该函数会返回一个 Promise
    • await 关键字用于等待一个 Promise 解决,它只能在 async 函数内部使用。

async/await 与异步行为

尽管 async/await 使得异步代码看起来像同步代码,但它实际上是异步执行的。以下是一些关键点来帮助理解这一点:

  1. 非阻塞执行:

    • 当你在 async 函数中使用 await 时,JavaScript会挂起该函数的执行,直到等待的 Promise 解决。在这个过程中,JavaScript运行时会继续执行其他任务,如事件处理、其他异步操作等。
  2. 事件循环:

    • await 并不会阻塞JavaScript的事件循环。相反,它允许事件循环在等待期间继续运行其他任务。
  3. 同步的写法,异步的执行:

    • async/await 提供了一种写异步代码的方式,使其看起来像同步代码。然而,这些代码仍然是异步执行的,因为它们不会阻塞主线程。

示例:理解 async/await 的异步行为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
async function asyncExample() {
console.log('开始执行异步函数');
await sleep(3000); // 假设这是一个返回 Promise 的异步 sleep 函数
console.log('异步函数执行完毕');
}

function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}

asyncExample();

// 即使 asyncExample 函数中的 await 暂停了函数的执行,控制台仍然会立即打印以下内容
console.log('异步函数执行后立即打印');

输出:

1
2
3
开始执行异步函数
异步函数执行后立即打印
异步函数执行完毕

在这个例子中,asyncExample 函数中的 await sleep(3000) 暂停了函数的执行,但并没有阻塞主线程。

因此,控制台会立即打印 "异步函数执行后立即打印",然后才打印 "异步函数执行完毕"

总结

使用 async/await 的代码仍然是异步执行的,因为它们不会阻塞JavaScript的事件循环。

async/await 提供了一种写异步代码的方式,使其看起来像同步代码,但它们实际上仍然是异步执行的。

这种方式使得异步代码更易于编写、阅读和维护。


异步函数 async

async 是一个关键字,用来声明一个函数是异步的。当你在一个函数前面加上 async,这个函数就会成为一个异步函数。异步函数可以运行 await 表达式,await 可以用来等待一个 Promise 解决(resolve)。

声明异步函数

当你在函数前加上 async 关键字时,这个函数会返回一个 Promise 对象。

1
2
3
async function myAsyncFunction() {
// ...
}

使用 await

在异步函数内部,你可以使用 await 关键字来等待一个 Promise
await 会暂停函数的执行,直到等待的 Promise 被解决(resolve)或拒绝(reject)。
如果 Promise 被解决,await 表达式的值就是 Promise 的值;如果 Promise 被拒绝,会抛出一个错误。

1
2
3
4
async function myAsyncFunction() {
let result = await somePromise(); // 等待 somePromise 解决
console.log(result); // somePromise 解决后的值
}

**错误处理

如果 awaitPromise 被拒绝,会抛出一个错误。
你可以使用 try...catch 语句来捕获这个错误。

1
2
3
4
5
6
7
8
9
10
11
12
async function myAsyncFunction() 
{
try
{
let result = await somePromise(); // 等待 somePromise 解决
console.log(result);
}
catch (error)
{
console.error('发生错误:', error);
}
}

返回值

async 函数总是返回一个 Promise
如果函数正常结束,Promise 会以函数的返回值解决;如果函数抛出错误,Promise 会以这个错误拒绝。

1
2
3
4
5
6
7
async function myAsyncFunction() {
return 'Hello, World!';
}

myAsyncFunction().then(greeting => {
console.log(greeting); // 输出:Hello, World!
});

链式 Promise

由于 async 函数返回 Promise,你可以链式调用多个 async 函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
async function myAsyncFunction1() 
{
return 'Hello';
}

async function myAsyncFunction2(greeting)
{
return `${greeting}, World!`;
}

myAsyncFunction1().then(greeting => {
return myAsyncFunction2(greeting);
}).then(result => {
console.log(result); // 输出:Hello, World!
}); //很明显这种“then等待promise”解决的代码看起来很累

使用 async/await,上述链式调用可以更简洁地写成:

1
2
3
4
5
6
async function chainAsyncFunctions() 
{
let greeting = await myAsyncFunction1();
let result = await myAsyncFunction2(greeting);
console.log(result); // 输出:Hello, World!
}

async/await 的好处是它让异步代码的写法更接近同步代码,使得代码更易于阅读和维护。

建立 sleep 函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* 异步 sleep 函数,等待指定的毫秒数
* @param {number} ms - 要等待的毫秒数
* @returns {Promise} - 解决后的Promise
*/


async function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}

// 使用 sleep 函数
async function doSomething() {
console.log('开始等待');
await sleep(3000); // 等待3秒
console.log('等待结束');
}

// 调用 doSomething 函数
doSomething();