Khi nào sử dụng promise tuần tự , khi nào sử dụng promise all?

Việc lựa chọn giữa Promise tuần tựPromise.all phụ thuộc vào yêu cầu cụ thể của tác vụ và mối quan hệ giữa các Promise. Dưới đây là hướng dẫn giúp bạn quyết định sử dụng loại nào:

1. Khi nào sử dụng Promise tuần tự?

Promise tuần tự là cách thực hiện các tác vụ bất đồng bộ lần lượt, từng Promise hoàn thành mới đến Promise tiếp theo.

Sử dụng Promise tuần tự khi:

  1. Các tác vụ có phụ thuộc lẫn nhau:
    • Tác vụ sau cần kết quả của tác vụ trước để tiếp tục.
  2. Cần kiểm soát thứ tự thực thi:
    • Dữ liệu hoặc logic yêu cầu phải thực hiện theo trình tự rõ ràng.
  3. Xử lý tuần tự giúp tối ưu tài nguyên:
    • Khi chỉ nên thực hiện một tác vụ tại một thời điểm để tránh quá tải hệ thống.

Ví dụ: Tác vụ phụ thuộc lẫn nhau

async function sequentialTasks() {
    const task1 = await new Promise((resolve) => setTimeout(() => resolve("Task 1 hoàn thành!"), 1000));
    console.log(task1);

    const task2 = await new Promise((resolve) => setTimeout(() => resolve(task1 + " -> Task 2 hoàn thành!"), 2000));
    console.log(task2);

    const task3 = await new Promise((resolve) => setTimeout(() => resolve(task2 + " -> Task 3 hoàn thành!"), 1000));
    console.log(task3);
}

sequentialTasks();

 

Task 1 hoàn thành!
Task 1 hoàn thành! -> Task 2 hoàn thành!
Task 1 hoàn thành! -> Task 2 hoàn thành! -> Task 3 hoàn thành!

2. Khi nào sử dụng Promise.all?

Promise.all cho phép thực thi song song nhiều Promise. Tất cả Promise sẽ được thực hiện đồng thời và trả về kết quả khi tất cả đều hoàn thành.

Sử dụng Promise.all khi:

  1. Các tác vụ độc lập, không phụ thuộc nhau:
    • Không yêu cầu kết quả từ một Promise để thực thi Promise khác.
  2. Cần tối ưu thời gian thực thi:
    • Chạy song song giúp giảm thời gian chờ đợi.
  3. Cần tổng hợp kết quả từ nhiều tác vụ:
    • Tất cả kết quả đều quan trọng và cần được xử lý cùng lúc.

Ví dụ: Tác vụ độc lập

async function parallelTasks() {
    const [result1, result2, result3] = await Promise.all([
        new Promise((resolve) => setTimeout(() => resolve("Task 1 hoàn thành!"), 1000)),
        new Promise((resolve) => setTimeout(() => resolve("Task 2 hoàn thành!"), 2000)),
        new Promise((resolve) => setTimeout(() => resolve("Task 3 hoàn thành!"), 1000))
    ]);

    console.log(result1, result2, result3);
}

parallelTasks();

Kết quả (sau khoảng 2 giây):

Task 1 hoàn thành! Task 2 hoàn thành! Task 3 hoàn thành!

 

So sánh Promise tuần tự và Promise.all

Tiêu chíPromise tuần tựPromise.all
Thứ tự thực thiTừng tác vụ, tuần tự, có kiểm soát.Thực thi đồng thời, không theo thứ tự.
Thời gian thực thiTổng thời gian = Tổng thời gian từng Promise.Tổng thời gian = Promise chậm nhất.
Quan hệ giữa các tác vụTác vụ phụ thuộc lẫn nhau.Các tác vụ độc lập, không phụ thuộc nhau.
Xử lý lỗiTừng lỗi được xử lý theo thứ tự.Một lỗi sẽ làm Promise.all thất bại.
Hiệu suấtHiệu suất thấp hơn nếu có nhiều Promise.Hiệu suất cao hơn khi các Promise chạy song song.

Kết hợp tuần tự và Promise.all:

Trong nhiều trường hợp, bạn cần sử dụng cả hai cách để tối ưu hiệu suất và đảm bảo thứ tự khi cần.

Ví dụ: Chạy từng nhóm song song

async function combinedTasks() {
    const group1 = await Promise.all([
        new Promise((resolve) => setTimeout(() => resolve("Group 1 - Task A"), 1000)),
        new Promise((resolve) => setTimeout(() => resolve("Group 1 - Task B"), 2000)),
    ]);
    console.log(group1);

    const group2 = await Promise.all([
        new Promise((resolve) => setTimeout(() => resolve("Group 2 - Task A"), 1000)),
        new Promise((resolve) => setTimeout(() => resolve("Group 2 - Task B"), 3000)),
    ]);
    console.log(group2);
}

combinedTasks();

 

["Group 1 - Task A", "Group 1 - Task B"]
["Group 2 - Task A", "Group 2 - Task B"]

 

Tóm lại:

  • Promise tuần tự: Khi các tác vụ phụ thuộc nhau hoặc cần thực thi theo thứ tự.
  • Promise.all: Khi các tác vụ độc lập và bạn cần tối ưu thời gian xử lý.