【JavaScript】网络请求之Promise fetch Axios及异步处理
Promise
Promise 表示承诺在未来的某个时刻可能会完成并返回结果,对于某些需要时间来处理结果的操作, 如用户登录、读取文件等, 可以使用 Promise 对象来执行异步操作
Promise 对象有三种状态 pending(待处理)、fulfilled(已履行)、rejected(被驳回)。
- 当创建一个 Promise 对象时, 它的初始状态为 pending, 表示异步执行还未完成;
- 当异步执行成功时, 会调用 resolve 函数把 Promise 对象的状态改变为 fulfilled, 可通过 then 方法来获取异步操作的结果;
- 当异步执行异常时, 会调用 reject 函数把 Promise 对象的状态更改为 rejected, 可通过 catch 方法来处理错误。
注:异步操作是指在程序执行过程中, 某个操作不会立即返回结果, 而是需要一段时间的等待
let promise = new Promise((resolve, reject) => {})
//当创建一个 Promise 对象时, 它的初始状态为 pending, 表示异步执行还未完成
console.log("promise:", promise) //pending
let promise = new Promise((resolve, reject) => {resolve("邮件发送成功") //异步执行成功
})
//当异步执行成功时, 会调用 resolve 函数把 Promise 对象的状态改变为 fulfilled, 可通过 then 方法来获取异步操作的结果
console.log("promise:", promise) //fulfilledpromise.then(result => {console.log("result:", result)
})
let promise = new Promise((resolve, reject) => {reject("邮件发送失败") //异步执行失败
})
//当异步执行失败时, 会调用 reject 函数把 Promise 对象的状态更改为 rejected, 可通过 catch 方法来处理错误
console.log("promise:", promise) //rejectedpromise.catch(error => {console.log("error:", error)
})
// resolve为自定义的执行成功后的函数
// reject为自定义的执行失败后的函数
let promise = new Promise((resolve, reject) => {//resolve("邮件发送成功")reject("邮件发送失败")
}).then(result => {console.log("result:", result)
}).catch(error => {console.log("error:", error)
}).finally(() => {console.log("异步执行结束")
})
fetch
fetch是基于Promise的api, 它可以发送http请求并接收服务器返回的响应数据,fetch 返回的是一个Promise对象。
//get请求
fetch('http://127.0.0.1/get').then(response => {//返回的解析后的json数据会传递给下一个 then() 方法中的回调函数作为参数,这个参数就是 datareturn response.json() //response.json() 用于将响应数据解析为json格式的数据
}).then(data => { //data 解析后的json数据console.log("get.data:", data)
}).catch(error => {console.log("get.error:", error.message)
}).finally(() => {console.log("get.finally")
})
//post请求 post
fetch('http://127.0.0.1/post', {method: 'POST',headers: {'Content-Type': 'application/x-www-form-urlencoded'}, body: new URLSearchParams({//URLSearchParams 用于处理键值对类型的数据,并将其编码为url查询字符串name: '小明',web: 'baidu.com',}),
}).then(response => {return response.json()
}).then(data => {console.log("post.data:", data)
}).catch(error => {console.log("post.error:", error.message)
}).finally(() => {console.log("post.finally")
})//post请求 postJson
fetch('http://127.0.0.1/postJson', {method: 'POST',headers: {'Content-Type': 'application/json',},body: JSON.stringify({//JSON.stringify 用于将对象转换为json字符串name: '小明',web: 'baidu.com',}),
}).then(response => {return response.json()
}).then(data => {console.log("postJson.data:", data)
}).catch(error => {console.log("postJson.error:", error.message)
}).finally(() => {console.log("postJson.finally")
})
Axios
Axios 是基于 Promise 的网络请求库, 它可以发送http请求并接收服务器返回的响应数据Axios返回的是一个Promise对象,Axios不仅可以用于浏览器, 也可以用于Node.js, 而Fetch主要用于浏览器。
//get请求
axios.get('http://127.0.0.1/get').then(response => {console.log("get.data:", response.data)
}).catch(error => {console.log("get.error:", error)
}).finally(() => {console.log("get.finally")
})
//post请求 post
let data = { //参数name: '小明',web: 'baidu.com',
}axios.post('http://127.0.0.1/post', data, {headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).then(response => {console.log("post.data:", response.data)
}).catch(error => {console.log("post.error:", error)
}).finally(() => {console.log("post.finally")
})//post请求 postJson [axios 的默认请求头是 application/json]
axios.post('http://127.0.0.1/postJson', data).then(response => {console.log("postJson.data:", response.data)
}).catch(error => {console.log("postJson.error:", error)
}).finally(() => {console.log("postJson.finally")
})
asycn await
同步:代码按照编写顺序逐行执行,后续的代码必须等待当前正在执行的代码完成之后才能执行。当遇到耗时的操作(如网络请求等)时,主线程会被阻塞,直到该操作完成。
异步:当遇到耗时的操作发生时, 主线程不会被阻塞, 主线程会继续执行后续的代码, 而非等待耗时操作完成。
async:当一个函数被标记为async后, 该函数会返回一个Promise对象。
await:只能在async函数内部使用, 加上await关键字后, 会在执行到这一行时暂停函数的剩余部分,等待网络请求完成,然后继续执行并获取到请求返回的数据。
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="axios/dist/axios.min.js"></script>
</head><body><script>//回调地狱是指过度使用嵌套的回调函数,导致代码难以阅读和维护//get请求axios.get('http://127.0.0.1/get').then(response => {console.log("get.data:", response.data)if (response.data.data.web == "baidu.com") {//get请求2return axios.get('http://127.0.0.1/article/get/id/1').then(response2 => {console.log("get2.data:", response2.data)if (response2.data.data.name == "邓瑞") {//get请求3return axios.get('http://127.0.0.1/article/get/search/title/入门').then(response3 => {console.log("get3.data:", response3.data)})}})}}).catch(error => {console.log("get.error:", error)}).finally(() => {console.log("get.finally")})//async/await 使用同步的方式编写异步代码, 避免回调地狱//优势 在处理多个异步操作的情况下, 可以使代码更简洁易读const getData = async () => {try {//get请求const response = await axios.get('http://127.0.0.1/get')console.log("async.get.data:", response.data)if (response.data.data.web === "baidu.com") {//get请求2const response2 = await axios.get('http://127.0.0.1/article/get/id/1')console.log("async.get2.data:", response2.data)if (response2.data.data.name === "小明") {//get请求3const response3 = await axios.get('http://127.0.0.1/article/get/search/title/入门')console.log("async.get3.data:", response3.data)}}} catch (error) {console.log("async.get.error:", error)} finally {console.log("async.get.finally")}}getData()</script>
</body>
</html>