
在 Pinia 中处理异步操作非常简单且灵活。Pinia 的 actions
支持同步和异步逻辑,因此你可以直接在 actions
中执行异步操作(如 API 请求、定时器等)。以下是处理异步操作的几种常见方式:
1. 在 actions
中直接处理异步操作
你可以在 actions
中直接使用 async/await
或 Promise
来处理异步操作。
示例:使用 async/await
// stores/user.ts
import { defineStore } from 'pinia';
export const useUserStore = defineStore('user', {
state: () => ({
user: null as any,
loading: false,
error: null as string | null,
}),
actions: {
async fetchUser(userId: number) {
this.loading = true;
this.error = null;
try {
const response = await fetch(`https://jsonplaceholder.typicode.com/users/${userId}`);
if (!response.ok) {
throw new Error('Failed to fetch user');
}
this.user = await response.json();
} catch (error) {
this.error = error instanceof Error ? error.message : 'Unknown error';
} finally {
this.loading = false;
}
},
},
});
在组件中使用
<template>
<div>
<p v-if="userStore.loading">Loading...</p>
<p v-else-if="userStore.error">Error: {{ userStore.error }}</p>
<div v-else>
<p>User: {{ userStore.user.name }}</p>
</div>
<button @click="fetchUser(1)">Fetch User</button>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { useUserStore } from '@/stores/user';
export default defineComponent({
setup() {
const userStore = useUserStore();
function fetchUser(userId: number) {
userStore.fetchUser(userId);
}
return {
userStore,
fetchUser,
};
},
});
</script>
2. 使用 Promise
处理异步操作
如果你更喜欢使用 Promise
,也可以在 actions
中使用。
示例:使用 Promise
// stores/user.ts
import { defineStore } from 'pinia';
export const useUserStore = defineStore('user', {
state: () => ({
user: null as any,
loading: false,
error: null as string | null,
}),
actions: {
fetchUser(userId: number) {
this.loading = true;
this.error = null;
fetch(`https://jsonplaceholder.typicode.com/users/${userId}`)
.then((response) => {
if (!response.ok) {
throw new Error('Failed to fetch user');
}
return response.json();
})
.then((data) => {
this.user = data;
})
.catch((error) => {
this.error = error instanceof Error ? error.message : 'Unknown error';
})
.finally(() => {
this.loading = false;
});
},
},
});
3. 在 actions
中调用其他 actions
你可以在一个 action
中调用另一个 action
,以实现逻辑复用。
示例:调用其他 action
// stores/user.ts
import { defineStore } from 'pinia';
export const useUserStore = defineStore('user', {
state: () => ({
user: null as any,
loading: false,
error: null as string | null,
}),
actions: {
async fetchUser(userId: number) {
this.loading = true;
this.error = null;
try {
const response = await fetch(`https://jsonplaceholder.typicode.com/users/${userId}`);
if (!response.ok) {
throw new Error('Failed to fetch user');
}
this.user = await response.json();
} catch (error) {
this.setError(error);
} finally {
this.loading = false;
}
},
setError(error: unknown) {
this.error = error instanceof Error ? error.message : 'Unknown error';
},
},
});
4. 处理并行异步操作
如果需要并行执行多个异步操作,可以使用 Promise.all
。
示例:并行异步操作
// stores/user.ts
import { defineStore } from 'pinia';
export const useUserStore = defineStore('user', {
state: () => ({
users: [] as any[],
loading: false,
error: null as string | null,
}),
actions: {
async fetchUsers(userIds: number[]) {
this.loading = true;
this.error = null;
try {
const promises = userIds.map((userId) =>
fetch(`https://jsonplaceholder.typicode.com/users/${userId}`).then((response) => {
if (!response.ok) {
throw new Error('Failed to fetch user');
}
return response.json();
})
);
this.users = await Promise.all(promises);
} catch (error) {
this.error = error instanceof Error ? error.message : 'Unknown error';
} finally {
this.loading = false;
}
},
},
});
5. 取消异步操作
如果需要取消异步操作(如取消 API 请求),可以使用 AbortController
。
示例:取消异步操作
// stores/user.ts
import { defineStore } from 'pinia';
export const useUserStore = defineStore('user', {
state: () => ({
user: null as any,
loading: false,
error: null as string | null,
abortController: null as AbortController | null,
}),
actions: {
async fetchUser(userId: number) {
if (this.abortController) {
this.abortController.abort(); // 取消之前的请求
}
this.abortController = new AbortController();
this.loading = true;
this.error = null;
try {
const response = await fetch(`https://jsonplaceholder.typicode.com/users/${userId}`, {
signal: this.abortController.signal,
});
if (!response.ok) {
throw new Error('Failed to fetch user');
}
this.user = await response.json();
} catch (error) {
if (error.name !== 'AbortError') {
this.error = error instanceof Error ? error.message : 'Unknown error';
}
} finally {
this.loading = false;
this.abortController = null;
}
},
cancelFetchUser() {
if (this.abortController) {
this.abortController.abort();
}
},
},
});
6. 在组合式 API 中使用异步操作
如果使用组合式 API 定义 Store,可以直接在 setup
函数中处理异步操作。
示例:组合式 API 中的异步操作
// stores/user.ts
import { defineStore } from 'pinia';
import { ref } from 'vue';
export const useUserStore = defineStore('user', () => {
const user = ref(null);
const loading = ref(false);
const error = ref<string | null>(null);
async function fetchUser(userId: number) {
loading.value = true;
error.value = null;
try {
const response = await fetch(`https://jsonplaceholder.typicode.com/users/${userId}`);
if (!response.ok) {
throw new Error('Failed to fetch user');
}
user.value = await response.json();
} catch (err) {
error.value = err instanceof Error ? err.message : 'Unknown error';
} finally {
loading.value = false;
}
}
return {
user,
loading,
error,
fetchUser,
};
});
总结
在 Pinia 中处理异步操作的方式包括:
- 在
actions
中使用async/await
或Promise
。 - 调用其他
actions
以实现逻辑复用。 - 使用
Promise.all
处理并行异步操作。 - 使用
AbortController
取消异步操作。 - 在组合式 API 中处理异步操作。
Pinia 的灵活性使得处理异步操作变得非常简单,适合各种复杂场景。
学在每日,进无止境!更多精彩内容请关注微信公众号。

原文出处:
内容由AI生成仅供参考,请勿使用于商业用途。如若转载请注明原文及出处。
出处地址:http://www.07sucai.com/tech/835.html
版权声明:本文来源地址若非本站均为转载,若侵害到您的权利,请及时联系我们,我们会在第一时间进行处理。