Xử lý đồng bộ một mảng bằng Promise thay cho async.eachSeries

Xử lý đồng bộ một mảng bằng Promise thay cho async.eachSeries

Tựa

Đang muốn chạy một hàm trong đó xử lý đồng bộ từng phần tử trong một mảng, do ghi vào DB nên có callback.

Có vài requirement:

  • Chạy NodeJS 6.x (support ES6)
  • Không dùng lib async (by Caolan) nữa (cũng một phần đang chuyển dần thói quen dùng ES7 với async await + Promise ở project đang làm)
  • Không dùng ES7 + Babel, thuần ES6 (do không liên quan đến cái đang làm kia mà chạy ở project cũ hơn)
  • Không hiểu sao viết generator function bị lỗi nên cũng không xài cái này luôn

Giải pháp: Sử dụng đệ quy cho xôi thịt

Giả sử có mảng như sau

let arr = [1, 2, 3];

Có hàm handleElement xử lý mỗi phần tử của mảng arr cho nhân lên với 2 và rất mất thời gian :v

function handleElement(number){
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            return resolve(number * 2);
        }, 1000);
    });
}

Tạo hàm gọi tạm là doSomething ý tưởng của hàm này là lấy từng phần tử của arr theo index, và chạy hàm handleElement, xong xuôi check nếu index chưa phải cái cuối cùng thì lại return lại hàm doSomething với index tăng lên 1.

function doSomething(index = 0){
    return new Promise((resolve, reject) => {
        handleElement(arr[index])
            .then((data) => {
                console.log(`result is ${data}`);

                if (index < arr.length - 1) {
                    return doSomething(index + 1);
                }
            })
            .then(() => {
                resolve('done');
            })
            .catch(reject);
    });
}

Chạy nào

doSomething()
    .then(console.log)
    .catch(console.log);

Kết quả

result is 2 //mất 1s
result is 4 //thêm 1s nữa
result is 6 //lại thêm 1s nữa 
done

Ps: Nếu muốn xử lý các element trong arr theo cách parallel, nhưng vẫn chờ đến khi toàn bộ arr được xử lý xong mới chạy tiếp thì dùng arr.map để ra một mảng mà mỗi phần tử là một Promise xử lý, tạm đặt tên là arrPs. Sau đó thì Promise.all(arrPs). Rồi làm gì thì làm.

Xbox: Mục đích là để chạy được nên độ xôi thịt rất cao, chưa nghĩ được solution native nào tốt hơn.

tuancuong92 14-10-2016

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Cuong Pham

11 bài viết.
0 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
7 1
Về cơ bản có 2 cách sử dụng Resolve/Reject trong Promise của Javascript: Sử dụng hàm static của class Promise: return Promise.reject() & return P...
Cuong Pham viết 1 năm trước
7 1
White
4 0
Generate Swagger API File to HTML Site Slate rất hay nhưng muốn gen từ Swagger API thì rất là lằng nhằng và tool convert có vẻ như tác giả không s...
Cuong Pham viết 1 năm trước
4 0
White
2 0
Test elasticsearch search keyword Elasticsearch là một db hỗ trợ tìm kiếm mạnh mẽ, nhưng đi kèm với nó là phải phân tích query và keyword. Analyz...
Cuong Pham viết hơn 1 năm trước
2 0
Bài viết liên quan
White
43 8
Tăng sức mạnh cho javascript với lodash Lần này mình sẽ giới thiệu 1 thư viện javascript vô cùng bá đạo có tên là "lodash]1]", có thể nói nó là LI...
Huy Hoàng Phạm viết hơn 2 năm trước
43 8
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
11 bài viết.
0 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!