Sử dụng Promise xử lý tác vụ bất đồng bộ trong Vue 3

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:

  1. Pending (Đang chờ): Trạng thái ban đầu, tác vụ chưa hoàn thành.
  2. Fulfilled (Đã hoàn thành): Tác vụ thành công và trả về một giá trị kết quả.
  3. 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

  1. Dữ liệu phản ứng (Reactive Data):
  • productList, isLoading, và errorMessage được tạo bằng ref để trở thành dữ liệu phản ứng. productList lưu trữ danh sách sản phẩm, isLoading theo dõi trạng thái tải, và errorMessage chứa thông báo lỗi khi có sự cố.
  1. 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ọi resolve với dữ liệu hoặc reject với thông báo lỗi.
  1. Xử lý Promise:
  • Trong hook onMounted, hàm retrieveProducts được gọi khi component được mount.
  • then xử lý khi thành công, gán dữ liệu vào productList.
  • catch xử lý khi có lỗi, lưu thông báo lỗi vào errorMessage.
  • finally đảm bảo isLoading được set thành false sau 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.

Thẻ: Vue3 JavaScript Async promise frontend

Đăng vào ngày 10 tháng 7 lúc 12:38