Trong JavaScript, Promise là một đối tượng được sử dụng để quản lý các tác vụ bất đồng bộ. Nó đại diện cho kết quả của một thao tác không đồng bộ, có thể là thành công hoặc thất bại. Promise mang lại cách tiếp cận gọn gàng và dễ đọc hơn so với việc sử dụng callback lồng nhau.
Các trạng thái của Promise
Một Promise có ba trạng thái chính:
- Pending (Đang chờ): Trạng thái ban đầu, tác vụ chưa hoàn thành.
- Fulfilled (Đã hoàn thành): Tác vụ thành công và trả về một giá trị kết quả.
- Rejected (Đã từ chối): Tác vụ thất bại và trả về nguyên nhân lỗi.
Ví dụ cơ bản về Promise
Dưới đây là một ví dụ đơn giản về cách tạo và sử dụng Promise:
// Khởi tạo một Promise mới
const asyncTask = new Promise((successCallback, failureCallback) => {
// Thực hiện tác vụ bất đồng bộ
setTimeout(() => {
const operationResult = true; // Giả lập kết quả tác vụ
if (operationResult) {
successCallback('Tác vụ đã hoàn thành'); // Thành công gọi successCallback
} else {
failureCallback('Tác vụ thất bại'); // Thất bại gọi failureCallback
}
}, 2000);
});
// Sử dụng Promise
asyncTask
.then(response => {
console.log(response); // Khi thành công: Tác vụ đã hoàn thành
})
.catch(err => {
console.error(err); // Khi thất bại: Tác vụ thất bại
})
.finally(() => {
console.log('Hoàn tất xử lý'); // Luôn luôn thực thi bất kể kết quả
});
Triển khai Promise trong component Vue 3
Ví dụ sau minh họa cách sử dụng Promise trong component Vue 3 để tải dữ liệu bất đồng bộ:
<template>
<div>
<p v-if="isLoading">Đang tải dữ liệu...</p>
<p v-else-if="errorMessage" class="error">{{ errorMessage }}</p>
<ul v-else>
<li v-for="product in productList" :key="product.id">
{{ product.title }} - {{ product.price }} USD
</li>
</ul>
</div>
</template>
<script>
import { ref, onMounted } from 'vue';
export default {
setup() {
const productList = ref([]);
const isLoading = ref(true);
const errorMessage = ref(null);
const retrieveProducts = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
// Giả lập lấy dữ liệu từ API
const fetchSuccess = true; // Thay đổi để test trường hợp lỗi
if (fetchSuccess) {
resolve([
{ id: 101, title: 'Sản phẩm A', price: 25 },
{ id: 102, title: 'Sản phẩm B', price: 40 },
{ id: 103, title: 'Sản phẩm C', price: 15 },
]);
} else {
reject('Không thể tải danh sách sản phẩm');
}
}, 2000);
});
};
onMounted(() => {
retrieveProducts()
.then(products => {
productList.value = products;
})
.catch(error => {
errorMessage.value = error;
})
.finally(() => {
isLoading.value = false;
});
});
return {
productList,
isLoading,
errorMessage,
};
},
};
</script>
<style>
.error {
color: #e74c3c;
}
</style>
Phân tích chi tiết
- Dữ liệu phản ứng (Reactive Data):
productList,isLoading, vàerrorMessageđược tạo bằngrefđể trở thành dữ liệu phản ứng.productListlưu trữ danh sách sản phẩm,isLoadingtheo dõi trạng thái tải, vàerrorMessagechứa thông báo lỗi khi có sự cố.
- Hàm
retrieveProducts:
- Hàm này trả về một Promise mới, giả lập việc gọi API lấy dữ liệu. Dựa vào giá trị của
fetchSuccess, nó sẽ gọiresolvevới dữ liệu hoặcrejectvới thông báo lỗi.
- Xử lý Promise:
- Trong hook
onMounted, hàmretrieveProductsđược gọi khi component được mount. thenxử lý khi thành công, gán dữ liệu vàoproductList.catchxử lý khi có lỗi, lưu thông báo lỗi vàoerrorMessage.finallyđảm bảoisLoadingđược set thànhfalsesau khi tác vụ hoàn tất, bất kể thành công hay thất bại.
Cách tiếp cận này giúp quản lý trạng thái bất đồng bộ một cách rõ ràng và có cấu trúc trong ứng dụng Vue 3.