Promise javascript: Serial and parallel

Nội dung bài viết

Promise javascript ra đời kể từ khi ES6 (ECMAScript 2015) chính thức giới thiệu, nhưng đến bây giờ việc sử dụng Serial Promise hay parallel Promise vẫn còn một số vấn đề mà còn nhiều developers vẫn chưa biết tận dụng hết khả năng của Promise.all(). Vậy trong bài viết này chúng tôi sẽ giới thiệu lại một lần nữa thông qua những ví dụ cụ thể.

Trước đây chúng tôi cũng đã giới thiệu về promise.all() ngay sau khi ES6 giới thiệu về tính năng này, và cũng có nhiều bài viết giải thích về cách sử dụng và khi nào sử dụng promise.all(). Nhưng gần đây, promise được sử dụng nhiều hơn trong trường hợp fetech data. Rút kinh nghiệm từ những bài viết trước, cho nên bài này chúng tôi sẽ tập trung vào code để giải thích cho developer javascript (devjs) hiểu sâu hơn.

Và sau đó đến khi ES8 (ECMAScript 2017) chính thức giới thiệu async/await để thay thế cho Promise nhưng cũng không hoàn toàn thay thế được, vì có những trường hợp như ví dụ dưới đây thì việc sử dụng Promise là quá hoàn hảo. Chúng ta hãy dành 1 phút đề xem ví dụ dưới đây.

À những bạn nào chưa học hết những tính năng từ ES6 đến ES11 thì đọc qua bài viết này, đã tóm tắt cụ thể cho bạn nào lười biếng luôn hêy: 

Tips: Tổng hợp tính năng javascript mới nhất kể từ ES6 đến ES11

Promise ES6

# Ví dụ 1: - Đối với serial Promise

function wait(waitTime) {
  return new Promise(resolve => setTimeout(() => {
    console.log(`waited ${waitTime} ms`)
    resolve()
  }, waitTime));
}

async function serial() {
  console.time('serial promise');
  await wait(1000);
  await wait(1000);
  await wait(1000);
  console.timeEnd('serial promise');
}

- Đối với Parallel Promise

function wait(waitTime) {
  return new Promise(resolve => setTimeout(() => {
    console.log(`waited ${waitTime} ms`)
    resolve()
  }, waitTime));
}

async function parallel() {
  console.time('parallel promise');
  await Promise.all([
    wait(1000),
    wait(1000),
    wait(1000)
  ])
  console.timeEnd('parallel promise');
}

Giờ test xem thằng nào chạy tối ưu hơn, không giải thích nhiều, rút kinh nghiệm những bài viết trước, giờ chạy code thôi

async function test() {
  await serial();
  await parallel();
}

Run: 

test();

Kết quả như hình dưới ta thấy, việc chạy tuần tự khiến chúng ta mất 3 giây, vì nó chạy lần lượt :

promise javascript

//serial 

  await wait(1000);
  await wait(1000);
  await wait(1000);

Mỗi lần chạy một giây => tổng mất 3 giây.

//parallel 

await Promise.all([
    wait(1000),
    wait(1000),
    wait(1000)
])

Chạy song song nên nó chỉ mất 1 giây để xử lý xong, giả sử ở trường hợp khác ta có

await Promise.all([
    wait(2000),
    wait(1000),
    wait(1000)
])

Thì các bạn đoán sẽ là bao nhiêu giây được trả về??? Đúng rồi đấy, mất 2 giây để trả về:

2 waited 1000 ms
waited 2000 ms
parallel promise: 2002.0888671875ms

Như vậy thì việc sử dụng promise all giúp chúng ta cải thiện rất nhiều trong việc tối ưu code của mình, bạn nào quan tâm đến performance javascript thì có thể vào series performance javascript

Giờ thì tôi nghĩ đến đây anh em devjs hiểu rõ hơn rồi. Nếu vậy thì bạn hãy quay lại bài viết này để hiểu thêm những trường hợp ta sử dụng promise.all trong es6 thế nào.

Tipjs: Promise.all javascript giúp tôi xử lý performance thế nào?

Còn bây giờ chúng ta thử đi lấy một ví dụ thực tế xem thế nào?

Ví dụ 2: Đầu tiên chúng ta sẽ tìm id của user thông qua name của user, sau đó từ id thì chúng ta sẽ có những comments và rating của User đó, thì thông thường chúng ta sẽ làm như thế này.

// GET method route using serial Promise
app.get('/', async (req, res) {
	let user = await Mongo_Model.findOne('name');
	let commentUser = await Mongo_Model.findOne(user.Id);
	let ratingUser = await Mongo_Model.findOne(user.Id);

        res.status(200).json({user, commentUser, ratingUser})
})

Nếu theo ví dụ 1 thì chúng ta có thể cải thiện performance khi sử dụng promise.all() và làm như thế nào?

// GET method route using parallel Promise
app.get('/', async (req, res) {
       //Câu hỏi này sẽ dành cho bạn nào đọc đến đây...
        res.status(200).json({user, commentUser, ratingUser})
})

Thanks for reading!