Bạn cần bật nút khi có ít nhất một dòng được chọn, hoặc khi mọi dòng đều hợp lệ. Hai yêu cầu nghe gần nhau nhưng trả lời khác nhau ở cả dữ liệu thường lẫn mảng rỗng. Dùng đúng phép kiểm tra giúp người review thấy quy tắc mà không phải giải mã một vòng lặp đếm.
Bài so sánh theo cùng tiêu chí: ý nghĩa Boolean, thời điểm dừng, case rỗng, yêu cầu runtime và chi phí tích hợp. Các snippet đã chạy bằng Node.js 24.18.1; tài liệu MDN được đối chiếu ngày 03/11/2026. Không có benchmark và không suy ra thứ hạng tốc độ cho dữ liệu sản phẩm.
Chạy hai câu hỏi trên cùng dữ liệu
Lưu thành predicates.cjs, chạy node predicates.cjs:
const assert = require('node:assert/strict');
const rows = [
{id: 1, valid: true},
{id: 2, valid: false},
{id: 3, valid: true},
];
assert.equal(rows.some(row => row.valid), true);
assert.equal(rows.every(row => row.valid), false);
assert.equal(rows.some(row => !row.valid), true);
let someCalls = 0;
let everyCalls = 0;
rows.some(row => { someCalls += 1; return row.valid; });
rows.every(row => { everyCalls += 1; return row.valid; });
assert.equal(someCalls, 1);
assert.equal(everyCalls, 2);
console.log('some/every fixture passed');
Các assertion đã qua. Trong fixture này, some tìm được một dòng hợp lệ ngay đầu; every gặp phản ví dụ ở dòng thứ hai. Số lần callback là bằng chứng cho đúng dữ liệu đang dùng, không phải phép đo thời gian xử lý hay cam kết tăng tốc bao nhiêu phần trăm.
Về quyền kiểm soát, cả hai nhận predicate do bạn định nghĩa và trả Boolean. Nếu cần chính phần tử hoặc tập phần tử, chúng không trả dữ liệu ấy thay bạn. Về tích hợp, không cần dependency ngoài; vẫn cần đối chiếu runtime mục tiêu nếu code chạy trong môi trường nhúng hoặc legacy.
Mảng rỗng cần được chốt trong yêu cầu
Chạy snippet độc lập:
const assert = require('node:assert/strict');
const rows = [];
let calls = 0;
const valid = row => { calls += 1; return row.valid; };
assert.equal(rows.some(valid), false);
assert.equal(rows.every(valid), true);
assert.equal(calls, 0);
const canSubmit = rows.length > 0 && rows.every(row => row.valid);
assert.equal(canSubmit, false);
console.log('empty-list policy passed');
Kết quả đã kiểm tra là some bằng false, every bằng true và không gọi predicate. every không tìm thấy phần tử nào vi phạm; điều này không đồng nghĩa đơn hàng rỗng được phép gửi. Dòng rows.length > 0 thể hiện yêu cầu ít nhất một phần tử một cách riêng biệt.
Trong review, hãy hỏi danh sách rỗng có hợp lệ hay không trước khi kết luận every bị lỗi. Với một bộ điều kiện tùy chọn, “không có điều kiện nào bị vi phạm” có thể đúng theo thiết kế. Với form bắt buộc chọn ít nhất một mục, cần thêm điều kiện về số lượng.
Giữ predicate đơn giản và đồng bộ
Các callback được kiểm tra dựa trên giá trị truthy hoặc falsy. Nếu trường valid chưa được chuẩn hóa, chuỗi 'false' vẫn truthy và có thể tạo kết quả khác yêu cầu. Ví dụ trong bài cố ý dùng Boolean thật, không nhận JSON bất kỳ rồi coi predicate là schema validator.
Không truyền một hàm async rồi kỳ vọng some hoặc every chờ kết quả mạng. Promise trả về không phải Boolean của kết quả đã hoàn thành. Với kiểm tra bất đồng bộ, cần một luồng chờ kết quả riêng trước khi áp dụng quy tắc quyết định; bài này chỉ đánh giá predicate đồng bộ.
Ngoài ra, các method bỏ qua empty slot của sparse array. Dữ liệu fixture là mảng đặc; điều kiện length > 0 một mình không chứng minh mọi vị trí đều chứa bản ghi hợp lệ. Kiểm tra cấu trúc đầu vào riêng nếu hệ thống có thể tạo mảng có lỗ.
Chọn theo câu hỏi cần trả lời
Dùng some khi một phần tử thỏa là đủ. Dùng every khi không được có phần tử vi phạm, và bổ sung điều kiện không rỗng nếu nghiệp vụ cần. Không thay thế lẫn nhau chỉ vì một cách viết nhìn ngắn hơn.
Với cùng bộ dữ liệu, hãy giữ test cho tất cả đúng, có một sai, tất cả sai và rỗng. Những case nhỏ ấy xác nhận hợp đồng rõ hơn một bài benchmark khi câu hỏi chính vẫn là nút có được bật hay không.


