Bạn có chắc chắn muốn xóa bài viết này không ?
Bạn có chắc chắn muốn xóa bình luận này không ?
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





