TypeScript入门 (五)异步编程与前后端交互

head-bar

引言

大家好,我是GISer Liu😁,一名热爱AI技术的GIS开发者。本系列文章是我跟随DataWhale 2024年9月学习赛的TypeScript学习总结文档。本文旨在全面介绍 TypeScript 中的异步编程与网络请求,帮助读者深入理解 TypeScript 中的 async/await、Promise、Fetch API、Axios、请求拦截器、响应拦截器、跨域处理等概念,以及在实际开发中的应用。💕💕😊


介绍

1.异步编程

在现代 Web 开发中,异步编程已经成为不可或缺的一部分。无论是从服务器获取数据、处理用户输入,还是执行复杂的计算任务,异步编程都能显著提升应用的性能和用户体验。

想象一下,如果一个网页在加载数据时需要等待所有操作完成才能继续,用户将会面临长时间的等待和卡顿,这显然是不可接受的。

异步编程的核心思想是允许程序在等待某些操作完成的同时,继续执行其他任务。这种方式不仅提高了程序的响应速度,还避免了因长时间等待而导致的资源浪费。

在 JavaScript 生态系统中,异步编程尤为重要,因为它是一种单线程语言,如果不采用异步机制,程序很容易陷入阻塞状态。

在TypeScript中,我们主要通过Promise和async/await进行一步编程,后者是前者的简化语法糖,具体内容我们在对应模块中进行详细介绍;

2.网络请求

在当下主流 Web 应用开发中,网络请求是获取和发送数据的重要手段。无论是从服务器获取数据,还是向服务器提交表单,网络请求都是不可或缺的。

在 TypeScript 中,常用的网络请求方法包括 XHRfetchaxios。它们的本质都是通过 HTTP 协议与服务器进行通信。fetchaxios 都基于 Promise,支持异步操作,使得我们可以使用 async/await 来简化异步代码的编写。

网络请求常常和异步编程相伴出现;这里作者联合两者,读者可以有一个更好的理解;

下面作者将两个模块分别进行描述!😘


一. TypeScript 中的异步编程模块

1.TypeScript 编译器与 ES5 标准

① TypeScript 默认使用 ES5 标准

TypeScript 是一种强类型的 JavaScript 超集,它通过编译器将 TypeScript 代码转换为 JavaScript 代码。默认情况下,TypeScript 编译器会将代码编译为 ES5 标准,以确保生成的 JavaScript 代码在大多数现代浏览器中都能正常运行。

ES5(ECMAScript 5)是 JavaScript 的一个早期标准,发布于 2009 年。尽管 ES5 提供了许多基础功能,但它并不包含一些现代 JavaScript 特性,如 Promise 对象和 async/await 语法。

② ES5 标准中不包含 Promise 对象

在 ES5 标准中,JavaScript 并没有内置的 Promise 对象Promise 是 ES6(ECMAScript 2015)引入的一个重要特性,用于处理异步操作。Promise 提供了一种更优雅的方式来处理异步操作的结果和错误,避免了传统的回调函数嵌套(即回调地狱)。

由于 TypeScript 默认编译为 ES5,因此在编写 TypeScript 代码时,如果需要使用 Promise,通常需要确保编译目标为 ES6 或更高版本。可以通过在 tsconfig.json 文件中设置 target 属性来指定编译目标:

{"compilerOptions": {"target": "ES6"}
}

2. async/await 简介

async/await 是 ES2017(ES8)的特性

async/await 是 ES2017(ES8)引入的语法特性,它建立在 Promise 之上,旨在进一步简化异步编程。async/await 允许开发者以同步代码的方式编写异步操作,从而提高代码的可读性和可维护性。

  • async 关键字用于声明一个异步函数,
  • await 关键字用于等待一个 Promise 的解析结果。
  • await 只能在 async 函数内部使用,它会使函数暂停执行,直到 Promise 被解析或拒绝。
async/await 如何简化异步编程

async/await 的主要优势在于它能够将异步代码转换为看起来像同步代码的形式,从而避免了回调地狱和复杂的 Promise 链式调用。以下是一个简单的示例,展示了如何使用 async/await 来处理异步操作:

// 定义一个返回 Promise 的异步函数
async function fetchData(): Promise<string> {return new Promise((resolve) => {setTimeout(() => {resolve("Data fetched successfully!");}, 1000);});
}// 使用 async/await 调用异步函数
async function main() {try {const result = await fetchData();console.log(result); // 输出: Data fetched successfully!} catch (error) {console.error("Error fetching data:", error);}
}main();

其中,fetchData 函数返回一个 Promise,模拟了一个异步操作。在 main 函数中,我们使用 await 关键字等待 fetchData 的结果,并将其赋值给 result 变量。如果 fetchData 成功,result 将包含解析后的值;如果失败,错误将被捕获并在 catch 块中处理。


3.使用 async/await 实现异步操作

①处理异步操作的延迟

在实际开发中,异步操作通常涉及网络请求、文件读取等需要时间完成的任务。我们可以使用 setTimeout 来模拟这些延迟操作。

// 定义一个返回 Promise 的异步函数,模拟延迟操作
async function asyncOperation(): Promise<number> {return new Promise((resolve) => {setTimeout(() => {resolve(10);}, 1000);  // 延迟 1000 毫秒(1 秒)});
}// 使用 async/await 调用异步函数
async function run() {const result = await asyncOperation();console.log(result);  // 输出: 10
}run();

asyncOperation 函数返回一个 Promise,该 Promise 会在 1000 毫秒后解析并返回数字 10

run 函数中,我们使用 await 关键字等待 asyncOperation 的结果。await 会使 run 函数暂停执行,直到 asyncOperation 返回的 Promise 被解析。一旦 Promise 被解析,result 变量将包含解析后的值,即 10

②串行执行多个异步操作

在某些场景下,我们需要按顺序执行多个异步操作,例如预先加载多个数据。await 关键字可以确保这些操作按顺序执行,即在前一个操作完成后再执行下一个操作。

// 定义两个返回 Promise 的异步函数,模拟延迟操作
async function asyncOperation1(): Promise<number> {return new Promise((resolve) => {setTimeout(() => {resolve(10);}, 1000);  // 延迟 1000 毫秒(1 秒)});
}async function asyncOperation2(): Promise<number> {return new Promise((resolve) => {setTimeout(() => {resolve(20);}, 1000);  // 延迟 1000 毫秒(1 秒)});
}// 使用 async/await 串行执行多个异步操作
async function run() {const result1 = await asyncOperation1();const result2 = await asyncOperation2();console.log(result1 + result2);  // 输出: 30
}run();

这里我们定义了两个异步函数 asyncOperation1asyncOperation2,它们分别返回一个 Promise,并在 1000 毫秒后解析。在 run 函数中,我们使用 await 关键字按顺序等待这两个异步操作的结果。await 确保 asyncOperation1 完成后才会执行 asyncOperation2,从而实现了串行执行。

通过这种方式可以避免数据还没有加载就执行了数据展示或处理的程序引发的报错!

③ 处理异步操作中的错误

在异步操作中,错误处理是非常重要的。我们可以使用 try...catch 块来捕获和处理异步操作中的错误。

// 定义一个返回 Promise 的异步函数,模拟可能出错的异步操作
async function asyncOperation(): Promise<number> {return new Promise((resolve, reject) => {setTimeout(() => {reject(new Error("Something went wrong"));}, 1000);  // 延迟 1000 毫秒(1 秒)});
}// 使用 async/await 调用异步函数,并使用 try...catch 块捕获错误
async function run() {try {const result = await asyncOperation();console.log(result);} catch (error) {console.error(error.message);  // 输出: Something went wrong}
}run();

asyncOperation 函数返回一个 Promise,该 Promise 会在 1000 毫秒后被拒绝,并抛出一个错误。在 run 函数中,我们使用 try...catch 块来捕获这个错误。如果 asyncOperation 成功,result 变量将包含解析后的值;如果失败,错误将被捕获并在 catch 块中处理。

错误处理在异步编程中非常重要,因为它可以帮助我们及时发现和处理潜在的问题,避免程序崩溃或产生不可预期的行为。

二、TypeScript中的网络请求模块

1. 网络请求的基本原理

① HTTP 协议

HTTP(Hypertext Transfer Protocol)是一种用于在网络上传输超文本文档的协议。它定义了客户端和服务器之间的通信规范,包括请求格式、响应格式、请求方法、状态码等

② 请求方法

HTTP 协议定义了几种常见的请求方法,其中最常用的是 GET 和 POST。

  • GET 请求:用于从服务器获取数据。GET 请求的参数会附加在 URL 后面,因此不适合传递敏感信息。
  • POST 请求:用于向服务器发送数据。POST 请求的参数会放在请求体中,因此适合传递敏感信息和大量数据。
③ 状态码

HTTP 状态码用于表示请求的处理结果。常见的状态码包括:

  • 2xx:成功状态码,表示请求成功。例如,200 OK 表示请求成功。
  • 3xx:重定向状态码,表示需要进一步操作才能完成请求。例如,301 Moved Permanently 表示资源已永久移动。
  • 4xx:客户端错误状态码,表示客户端请求有误。例如,404 Not Found 表示请求的资源不存在。
  • 5xx:服务器错误状态码,表示服务器处理请求时出错。例如,500 Internal Server Error 表示服务器内部错误。

2. Fetch API 的使用

Fetch API 是一个现代化的网络请求 API,它基于 Promise,可以用于发送和接收网络请求。

① Fetch API 的基本用法
fetch('https://api.example.com/data').then(response => response.json()).then(data => console.log(data)).catch(error => console.error('Error:', error));

这里我们分析一下这个过程:

1.创建请求:使用 fetch 函数创建一个请求。

2.发送请求fetch 函数会发送请求到指定的 URL。

3.接收响应:服务器返回响应后,fetch 函数会返回一个 Response 对象。

4.处理响应:通过 Response 对象的方法(如 json())处理响应数据,将数据转化为json格式方便处理。

5.输出或抛出错误:如果数据如期解析成功,就会在控制台输出数据,如果报错则会输出错误;

② Fetch API 的优缺点
  • 优点:语法简单、基于 Promise、支持跨域请求、支持流数据。
  • 缺点兼容性不佳、缺乏细节控制、只能捕获网络错误

3. Axios 的使用

Axios 是一个基于 Promise 的 HTTP 客户端,广泛用于浏览器和 Node.js 环境中。

①Axios 的基本用法
import axios from 'axios';axios.get('https://api.example.com/data').then(response => console.log(response.data)).catch(error => console.error('Error:', error));
② Axios 的请求流程
  1. 创建请求:使用 axios 函数创建一个请求。
  2. 发送请求axios 函数会发送请求到指定的 URL。
  3. 接收响应:服务器返回响应后,axios 函数会返回一个包含响应数据的 Promise。
  4. 处理响应:通过 .then() 方法处理响应数据。
③ Axios 的配置选项

Axios 提供了丰富的配置选项,可以用于自定义请求的行为。

axios({method: 'post',url: 'https://api.example.com/data',data: {firstName: 'John',lastName: 'Doe'}
}).then(response => console.log(response.data)).catch(error => console.error('Error:', error));
④ Axios 的拦截器

Axios 支持请求拦截器和响应拦截器,可以在请求发送前或响应返回后进行额外的处理。

4. 请求拦截器与响应拦截器

①请求拦截器

请求拦截器允许我们在请求发送前对请求配置进行修改或添加额外的逻辑。常见的使用场景包括:

  • 添加认证信息:在请求头中添加认证信息(如 JWT Token)。
  • 设置全局请求头:为所有请求设置相同的请求头(如 Content-Type)。
  • 请求日志记录:记录请求的详细信息,便于调试和监控。
  • 请求重试:在请求失败时自动重试。

假设我们有一个需要认证的 API,每次请求都需要在请求头中添加 JWT Token。通过请求拦截器,我们可以在每次请求前自动添加 Token,而不需要在每个请求中手动设置。

代码如下:

import axios from 'axios';// 创建一个 Axios 实例
const instance = axios.create({baseURL: 'https://api.example.com', //设置基础 URL 和最大请求超时时间。timeout: 10000,
});// 添加请求拦截器
instance.interceptors.request.use((config) => {// 在发送请求之前做些什么const token = localStorage.getItem('token'); // 在请求发送前,从 localStorage 中获取 Token,并将其添加到请求头中。然后记录请求配置信息if (token) {config.headers.Authorization = `Bearer ${token}`;}console.log('Request Config:', config);return config;},(error) => {// 对请求错误做些什么console.error('Request Error:', error);return Promise.reject(error);}
);// 发送请求
instance.get('/data').then(response => console.log(response.data)).catch(error => console.error('Error:', error));

请求拦截器就讲到这里,更多应用还是得实践尝试!

② 响应拦截器

响应拦截器允许我们在响应返回后对响应数据进行处理或添加额外的逻辑。常见的使用场景包括:

  • 统一处理响应数据:对响应数据进行格式化或解密。
  • 错误处理:统一处理服务器返回的错误信息。
  • 响应日志记录:记录响应的详细信息,便于调试和监控。
  • 权限校验:在响应中检查用户权限,并根据权限进行相应的操作。

假设我们的 API 返回的数据格式是 JSON,但在某些情况下,服务器可能会返回错误信息。通过响应拦截器,我们可以在响应返回后统一处理错误信息,并根据错误类型进行相应的操作。

下面是个代码案例:

import axios from 'axios';// 创建一个 Axios 实例
const instance = axios.create({baseURL: 'https://api.example.com',timeout: 10000,
});// 添加响应拦截器
instance.interceptors.response.use((response) => {// 对响应数据做点什么console.log('Response Data:', response.data);return response.data;},(error) => {// 对响应错误做点什么if (error.response) {// 服务器返回了错误响应console.error('Server Error:', error.response.data);switch (error.response.status) {case 401:// 未授权,跳转到登录页面window.location.href = '/login';break;case 404:// 资源未找到,显示错误信息console.error('Resource Not Found');break;default:// 其他错误,显示通用错误信息console.error('An error occurred');}} else if (error.request) {// 请求已发送但未收到响应console.error('No Response Received:', error.request);} else {// 其他错误console.error('Request Error:', error.message);}return Promise.reject(error);}
);// 发送请求
instance.get('/data').then(data => console.log(data)).catch(error => console.error('Error:', error));
  • 成功回调:在响应返回后,记录响应数据并返回处理后的数据。
  • 错误回调:在响应发生错误时,根据错误类型进行相应的处理:
  • 服务器返回错误响应:根据状态码进行不同的处理(如 401 跳转到登录页面,404 显示资源未找到信息)。
  • 请求已发送但未收到响应:记录未收到响应的请求信息。
  • 其他错误:记录请求错误信息。

三、案例实践

这里作者基于实现一个全栈案例Demo,下面是技术栈:

  • 前端:Vue3 +TypeScript
  • 后端:FastAPI + Python
  • 网络请求:Axios

1 环境搭建

① 项目创建

Vite 是一个现代化的前端构建工具,它提供了快速的开发体验。我们可以使用 Vite 快速创建一个 Vue 3 + TypeScript 项目。

  1. 安装 Vite
npm install -g create-vite
  1. 创建vite项目
npm create vite
  1. 选择项目模板

  1. 选择 TypeScript 支持

  1. 进入项目目录并安装依赖

② 项目启动

安装完依赖后,可以使用以下命令启动开发服务器:

npm run dev

启动成功!

2. 单文件组件(SFC)

① 介绍 Vue 的单文件组件(SFC)

Vue 的单文件组件(SFC)是一种将模板、逻辑和样式封装在一个文件中的组件格式。SFC 使用 .vue 文件扩展名,通常包含以下三个部分:

  • <template>:定义组件的 HTML 模板。
  • <script>:定义组件的逻辑,通常使用 TypeScript。
  • <style>:定义组件的样式。

如下图中APP.vue文件内容所示;

② 展示 HelloWorld.vue 组件的代码
<template><div class="hello"><h1>{{ msg }}</h1></div></template><script lang="ts">
import { defineComponent } from 'vue';export default defineComponent({name: 'HelloWorld',props: {msg: {type: String,required: true,},},
});
</script><style scoped>
.hello {font-family: Avenir, Helvetica, Arial, sans-serif;text-align: center;color: #2c3e50;margin-top: 60px;
}
</style>

3. 引入 Axios 进行网络请求

① 在 TypeScript 中使用 Axios 进行网络请求

首先,我们需要安装 Axios:

npm install axios
② 发起 GET 和 POST 请求

在 Vue 组件中使用 Axios 发起 GET 和 POST 请求:

<template><div><h1>Axios 案例测试</h1><button @click="fetchPosts">获取100篇文章数据</button><button @click="fetchPostById">根据文章ID获取文章数据</button><button @click="addPost">添加文章</button><button @click="fetchCatImage">随机获取1张猫图</button><button @click="fetchDogImage">随机返回一张狗子照片</button><button @click="fetchRandomImage">返回随机图片</button><div v-if="data"><pre>{{ data }}</pre></div><div v-if="imageUrl"><img :src="imageUrl" alt="图片" /></div><div v-if="quote"><p>{{ quote }}</p></div></div>
</template><script lang="ts">
import { defineComponent } from 'vue';
import axios from 'axios';export default defineComponent({name: 'AxiosExample',data() {return {data: null,imageUrl: null,quote: null,};},methods: {async fetchPosts() {try {const response = await axios.get('https://jsonplaceholder.typicode.com/posts');this.data = JSON.stringify(response.data, null, 2);} catch (error) {console.error('获取文章数据失败:', error);}},async fetchPostById() {try {const response = await axios.get('https://jsonplaceholder.typicode.com/posts/2');this.data = JSON.stringify(response.data, null, 2);} catch (error) {console.error('获取指定文章数据失败:', error);}},async addPost() {try {const response = await axios.post('https://jsonplaceholder.typicode.com/posts', {title: 'foo',body: 'bar',userId: 1,});this.data = JSON.stringify(response.data, null, 2);} catch (error) {console.error('添加文章失败:', error);}},async fetchCatImage() {try {const response = await axios.get('https://api.thecatapi.com/v1/images/search?limit=1');this.imageUrl = response.data[0].url;} catch (error) {console.error('获取猫图失败:', error);}},async fetchDogImage() {try {const response = await axios.get('https://dog.ceo/api/breeds/image/random');this.imageUrl = response.data.message;} catch (error) {console.error('获取狗子照片失败:', error);}},async fetchRandomImage() {try {const response = await axios.get('https://picsum.photos/200/300');this.imageUrl = response.request.responseURL;} catch (error) {console.error('获取随机图片失败:', error);}},},
});
</script><style scoped>
/* 你可以在这里添加一些样式 */
</style>

这里由于时间问题,UI相对还是有点粗糙;😂

当然我们这里成功加载了一些公共服务的API,我们也可以自己搭建后端获取数据,下面我们简单介绍一下使用Python语言基于FastAPI框架进行后端搭建的Demo;

4. 使用 FastAPI 搭建后端服务

① 安装和配置 FastAPI

FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API。我们可以使用 FastAPI 快速搭建一个后端服务。

  1. 安装 FastAPI 和 Uvicorn
pip install fastapi uvicorn
  1. 创建一个简单的 FastAPI 应用
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddlewareapp = FastAPI()# 添加 CORS 中间件,避免跨域错误
app.add_middleware(CORSMiddleware,allow_origins=["*"],  # 允许所有来源allow_credentials=True,allow_methods=["*"],  # 允许所有方法allow_headers=["*"],  # 允许所有头
)@app.get("/data")
async def get_data():return {"message": "Hello, World!"}@app.post("/data")
async def add_data(name: str, age: int):return {"name": name, "age": age}
  1. 启动 FastAPI 服务:这里文件名为 main.py
uvicorn main:app --reload 

② 后端测试代码

我们可以使用 Postman 或 curl 测试后端服务:

  • GET 请求
curl http://127.0.0.1:8000/data

  • POST 请求
curl.exe -X POST "http://127.0.0.1:8000/data?name=John%20Doe&age=30"

③ 前端与后端的交互

在 Vue 组件中使用 Axios 与 FastAPI 后端进行交互:

这里我们将刚刚的get测试和post测试也加入到vue3程序中;

<template><div><h1>Axios 案例测试</h1><button @click="fetchPosts">获取100篇文章数据</button><button @click="fetchPostById">根据文章ID获取文章数据</button><button @click="addPost">添加文章</button><button @click="fetchCatImage">随机获取1张猫图</button><button @click="fetchDogImage">随机返回一张狗子照片</button><button @click="fetchRandomImage">返回随机图片</button><button @click="fetchLocalData">获取本地数据</button><button @click="addLocalData">添加本地数据</button><div v-if="data"><pre>{{ data }}</pre></div><div v-if="imageUrl"><img :src="imageUrl" alt="图片" /></div><div v-if="quote"><p>{{ quote }}</p></div></div>
</template><script lang="ts">
import { defineComponent } from 'vue';
import axios from 'axios';export default defineComponent({name: 'AxiosExample',data() {return {data: null,imageUrl: null,quote: null,};},methods: {async fetchPosts() {try {const response = await axios.get('https://jsonplaceholder.typicode.com/posts');this.data = JSON.stringify(response.data, null, 2);} catch (error) {console.error('获取文章数据失败:', error);}},async fetchPostById() {try {const response = await axios.get('https://jsonplaceholder.typicode.com/posts/2');this.data = JSON.stringify(response.data, null, 2);} catch (error) {console.error('获取指定文章数据失败:', error);}},async addPost() {try {const response = await axios.post('https://jsonplaceholder.typicode.com/posts', {title: 'foo',body: 'bar',userId: 1,});this.data = JSON.stringify(response.data, null, 2);} catch (error) {console.error('添加文章失败:', error);}},async fetchCatImage() {try {const response = await axios.get('https://api.thecatapi.com/v1/images/search?limit=1');this.imageUrl = response.data[0].url;} catch (error) {console.error('获取猫图失败:', error);}},async fetchDogImage() {try {const response = await axios.get('https://dog.ceo/api/breeds/image/random');this.imageUrl = response.data.message;} catch (error) {console.error('获取狗子照片失败:', error);}},async fetchRandomImage() {try {const response = await axios.get('https://picsum.photos/200/300');this.imageUrl = response.request.responseURL;} catch (error) {console.error('获取随机图片失败:', error);}},async fetchLocalData() {try {const response = await axios.get('http://127.0.0.1:8000/data');this.data = JSON.stringify(response.data, null, 2);} catch (error) {console.error('获取本地数据失败:', error);}},async addLocalData() {try {const response = await axios.post('http://127.0.0.1:8000/data?name=John Doe&age=30');this.data = JSON.stringify(response.data, null, 2);} catch (error) {console.error('添加本地数据失败:', error);}},},
});
</script><style scoped>
/* 你可以在这里添加一些样式 */
</style>

经过测试,获取成功!!

如果存在网络问题,看看是不是后端没有配置跨域CORS中间件或者后端项目是否启动;

5. 封装 Axios (可选)

①为什么要封装 Axios

Axios 可以带来以下好处:

  • 代码复用:将常用的请求逻辑封装起来,避免重复代码。
  • 统一配置:统一管理请求的配置,如基础 URL、请求头、拦截器等。
  • 错误处理:统一处理请求错误,减少重复的错误处理逻辑。
  • 类型安全:使用 TypeScript 定义接口类型,提升代码的类型安全性。
② 代码实践
  • 在 base.ts 文件中创建 Axios 实例

创建一个 base.ts 文件,用于创建 Axios 实例并设置请求和响应拦截器:

import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';const instance: AxiosInstance = axios.create({baseURL: 'http://127.0.0.1:8000',timeout: 10000,
});// 请求拦截器
instance.interceptors.request.use((config: AxiosRequestConfig) => {const token = localStorage.getItem('token');if (token) {config.headers.Authorization = `Bearer ${token}`;}return config;},(error) => {return Promise.reject(error);}
);// 响应拦截器
instance.interceptors.response.use((response: AxiosResponse) => {return response.data;},(error) => {return Promise.reject(error);}
);export default instance;
③ 定义接口类型

创建一个 type.ts 文件,用于定义接口类型:

export interface DataResponse {message: string;
}export interface CreateDataRequest {name: string;age: number;
}export interface CreateDataResponse {name: string;age: number;
}

通过定义接口类型,我们可以在编写代码时获得 TypeScript 的类型检查功能,减少类型错误。

④ 封装请求方法

创建一个 api.ts 文件,用于封装请求方法:

import axios from './base';
import { DataResponse, CreateDataRequest, CreateDataResponse } from './type';export const fetchData = async (): Promise<DataResponse> => {const response = await axios.get<DataResponse>('/data');return response;
};export const createData = async (data: CreateDataRequest): Promise<CreateDataResponse> => {const response = await axios.post<CreateDataResponse>('/data', data);return response;
};

api.ts 文件中,我们封装了 fetchDatacreateData 方法,并在方法中使用 TypeScript 的类型注解,确保请求和响应的类型安全。

⑤ 在组件中使用封装的 Axios

在 Vue 组件中直接使用封装的请求方法:

<template><div><h1>API Example</h1><button @click="fetchData">Fetch Data</button><button @click="sendData">Send Data</button><div v-if="data"><pre>{{ data }}</pre></div></div></template><script lang="ts">
import { defineComponent } from 'vue';
import { fetchData, createData } from './api';export default defineComponent({name: 'APIExample',data() {return {data: null,};},methods: {async fetchData() {try {this.data = await fetchData();} catch (error) {console.error('Error fetching data:', error);}},async sendData() {try {this.data = await createData({ name: 'John Doe', age: 30 });} catch (error) {console.error('Error sending data:', error);}},},
});
</script>

在 Vue 组件的方法中,我们可以直接使用 await 关键字调用封装的请求方法,简化异步代码的编写。

⑥ 使用 async/await 处理请求

在 Vue 组件的方法中使用 async/await 处理请求:

methods: {async fetchData() {try {this.data = await fetchData();} catch (error) {console.error('Error fetching data:', error);}},async sendData() {try {this.data = await createData({ name: 'John Doe', age: 30 });} catch (error) {console.error('Error sending data:', error);}},
}

async 函数中,我们可以使用 await 关键字等待异步操作完成,并将结果赋值给组件的 data 属性。通过这种方式,我们可以更简洁地处理异步请求。


Over,作者的总结完毕!😘👌😊 本次学习总结到此结束!!🙂 各位读者可以参考本文通过代码实践来加深理解!😉

相关链接

  • 项目地址:TypeScript-CookBook
  • 相关文档:专栏地址
  • 作者主页:GISer Liu-CSDN博客

thank_watch

如果觉得我的文章对您有帮助,三连+关注便是对我创作的最大鼓励!或者一个star🌟也可以😂.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/434273.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

通信工程学习:什么是MAI多址干扰

MAI:多址干扰 MAI多址干扰(Multiple Access Interference)是无线通信领域,特别是在码分多址(CDMA)系统中,一个关键的干扰现象。以下是对MAI多址干扰的详细解释: 一、定义 多址干扰是指在CDMA系统中,由于多个用户的信号在时域和频域上是混叠的,从而导…

PCB基础

一、简介 PCB&#xff1a;printed circuit board&#xff0c;印刷电路板 主要作用&#xff1a;传输信号、物理支撑、提供电源、散热 二、分类 2.1 按基材分类 陶瓷基板&#xff1a;包括氧化铝、氮化铝、碳化硅基板等&#xff0c;具有优异的导热性&#xff0c;适用于高温和高…

前缀和(包括一维和二维)

前缀和 什么是前缀和&#xff1f;用在哪里&#xff1f;有什么好处&#xff1f; 前缀和是在反复求一个序列中不同区间处的元素之和。 例如有以下一个数组&#xff1a;1&#xff0c;2&#xff0c;3&#xff0c;4&#xff0c;5 我们要求a[2]~a[4]&#xff08;不包括a[2]&#xff0…

css边框修饰

一、设置线条样式 通过 border-style 属性设置&#xff0c;可选择的一些属性如下&#xff1a; dotted&#xff1a;点线 dashed&#xff1a;虚线 solid&#xff1a;实线 double&#xff1a;双实线 效果如下&#xff1a; 二、设置边框线宽度 ① 通过 border-width 整体设置…

从碎片到整合:EasyCVR平台如何重塑城市感知系统的视频数据生态

随着城市化进程的加速&#xff0c;城市感知系统作为智慧城市的重要组成部分&#xff0c;正逐步成为提升城市管理效率、保障公共安全、优化资源配置的关键手段。EasyCVR视频汇聚融合平台&#xff0c;凭借其强大的数据整合、智能分析与远程监控能力&#xff0c;在城市感知系统中扮…

使用 PowerShell 命令更改 RDP 远程桌面端口(无需修改防火墙设置)

节选自原文&#xff1a;Windows远程桌面一站式指南 | BOBO Blog 原文目录 什么是RDP&#xfffc;开启远程桌面 检查系统版本启用远程桌面连接Windows 在Windows电脑上在MAC电脑上在Android或iOS移动设备上主机名连接 自定义电脑名通过主机名远程桌面使用Hosts文件自定义远程主…

依赖注入之set注入

set注入 set注入&#xff0c;基于set王法实现的&#xff0c;底层通过反射机制调用属性对应的set方法&#xff0c;然后给属性赋值&#xff0c;这种方法要求属性必须对外提供set方法 1. 想让Spring调用对应的set方法&#xff0c;需要配置property标签 2. name属性怎么指定值:s…

云计算Openstack

OpenStack是一个开源的云计算管理平台项目&#xff0c;由美国国家航空航天局&#xff08;NASA&#xff09;和Rackspace公司合作研发并发起&#xff0c;以Apache许可证授权。该项目旨在为公共及私有云的建设与管理提供软件支持&#xff0c;通过一系列相互协作的组件实现云计算服…

python和pyqt-tools安装位置

一.python的安装位置 1.查询安装的python的位置 先查询python&#xff0c;然后输入import sys和sys.path 二.python-tools的安装位置 找到python的文件后按下图路径即可查到tools的文件

利士策分享,攀登职场高峰:成功者的十大特质

利士策分享&#xff0c;攀登职场高峰&#xff1a;成功者的十大特质 在职场这个竞争激烈的舞台上&#xff0c;那些能够迅速崛起、实现职业辉煌的佼佼者&#xff0c;往往凭借一系列独特且鲜明的特质脱颖而出。以下是对这些特质的深入探讨&#xff1a; 第一章&#xff1a;高情商的…

AI芯片WT2605C赋能厨房家电,在线对话操控,引领智能烹饪新体验:尽享高效便捷生活

在智能家居的蓬勃发展中&#xff0c;智能厨电作为连接科技与生活的桥梁&#xff0c;正逐步渗透到每一个现代家庭的厨房中。蒸烤箱作为智能厨电的代表&#xff0c;以其丰富的功能和高效的性能&#xff0c;满足了人们对美食的多样化追求。然而&#xff0c;面对众多复杂的操作功能…

【CSS】字体文本

color 颜色font-size 大小font-family 字体font-style 样式font-weight 加粗text-decoration 下划线text-shadow 阴影text-transform 大小写变换text-indent 缩进text-align 水平对齐 、vertical-align垂直对齐text-overflow 溢出word-wrap 换行word-break 截断white-space 空白…

How to install JetBrains ToolBox in Ubuntu 22.04 LTS?

JetBrains Toolbox 的安装教程 在 2024 年 9 月 28 日&#xff0c;我想和大家分享一下 JetBrains Toolbox 的安装步骤&#xff0c;让你轻松开启高效的开发之旅。 一、准备工作 首先&#xff0c;确保你已经准备好了要安装的 JetBrains Toolbox 文件&#xff0c;可以从官方网站…

(undone) MIT6.824 Lecture1 笔记

参考1MIT课程视频&#xff1a;https://www.bilibili.com/video/BV16f4y1z7kn/?spm_id_from333.337.search-card.all.click&vd_source7a1a0bc74158c6993c7355c5490fc600 参考2某大佬笔记&#xff1a;https://ashiamd.github.io/docsify-notes/#/study/%E5%88%86%E5%B8%83%…

计算机网络详解:发展史、TCP/IP协议、网络通信与应用开发全流程

文章目录 1. 计算机网络的发展史1.1 初期阶段&#xff1a;网络的萌芽&#xff08;1960年代&#xff09;1.2 第二阶段&#xff1a;TCP/IP协议的引入&#xff08;1970-1980年代&#xff09;1.3 第三阶段&#xff1a;互联网的普及与商业化&#xff08;1990年代&#xff09;1.4 现代…

[数据集][目标检测]猪数据集VOC-2856张

数据集格式&#xff1a;Pascal VOC格式(不包含分割的txt文件&#xff0c;仅仅包含jpg图片和对应的xml) 图片数量(jpg文件个数)&#xff1a;2856 标注数量(xml文件个数)&#xff1a;2856 标注类别数&#xff1a;1 标注类别名称:["pig"] 每个类别标注的框数&#xff1a…

The 2024 CCPC Online Contest (C I J三题思路)

写在前面 因为学弟已经问了几个题了&#xff0c;于是乎这场没有vp&#xff0c;准备直接开写了 题目 C. 种树&#xff08;树形dp&#xff09; 题解 只有两种情况&#xff0c; 一种是1-2-3&#xff0c;1是2的父亲&#xff0c;2是3的父亲 另一种是1-2-3&#xff0c;2同时是1…

Meta AI 发布 Llama 3.2

Llama 3.2新闻 Meta公司在其Connect大会上宣布了Llama 3.2的发布&#xff0c;这是其首款能够理解图像和文本的旗舰视觉模型。Llama 3.2包含中型和小型两个版本&#xff08;分别拥有11B与90B参数&#xff09;&#xff0c;以及更轻量化的纯文本模型&#xff08;分别拥有1B与3B参数…

基于 RealSense D435相机实现手部姿态检测

基于 RealSense D435i相机进行手部姿态检测&#xff0c;其中采用 Mediapipe 进行手部检测&#xff0c;以下是详细步骤&#xff1a; Mediapipe 是一个由 Google开发的开源框架&#xff0c;专门用于构建多媒体处理管道&#xff0c;特别是计算机视觉和机器学习任务。它提供了一系列…

并查集 (Union-Find) :从基础到优化

并查集 (Union-Find) 并查集是一种树形数据结构&#xff0c;主要用于处理不相交集合&#xff08;Disjoint Set&#xff09;的合并和查询问题。它特别适用于解决有关连通性的问题&#xff0c;比如在图论中判断两点是否在同一个连通分量中。并查集可以高效地支持以下两种操作&am…