Vấn đề
Khi dùng một số thư viện phổ biến như mongoose, supabase thì ta sẽ bắt gặp một số syntax như sau.
Await nhận về kết quả khi query tất cả field
Await sau khi đã thêm order và limit query
Ta có thể thấy được một điều khá kì lạ rằng bình thường ta chỉ có thể dùng await với một Promise được trả về, nhưng theo ví dụ thì giá trị được trả về sau .select() không phải là một promise mà còn là một class chứa các method khác để query, nhưng ta lại vẫn có thể await class đó. Và bài post này sẽ giúp bạn tìm hiểu về await khi áp dụng với một Class trong javascript, đây gọi là class "Thenable"
Bắt đầu code
Khởi tạo một Class có tên query và thêm vào các method đặc biệt cho việc demo giống với thư viện trong ví dụ trên.
class Query { constructor() { this.steps = []; } find() { this.steps.push("Find"); return this; } limit(num) { this.steps.push(`Limit ${num}`); return this; }}
Giờ ta thêm một method đặc biệt vào class này
class Query { // ...... async then(resolve, reject) { resolve(this.steps); }}
Method then() trong class rất đặc biệt và nhận vào hai parameters là resolve và reject để resolve cái promise.
const query = new Query();(async () => { const data = await query.find().limit(10); console.log(data); // Log: [ 'Find', 'Limit 10' ] const data2 = await query.find(); console.log(data2); // Log: [ 'Find' ]})();
Ta có thể thấy rằng khi sử dụng await trong javascript nếu như đối tượng không phải một Promise, nó sẽ tự động tìm đến method .then của đối tượng đó và thực hiện rồi trả về kết quả như mong muốn
Code hoàn chỉnh
Kết luận
Và đó là cách sử dụng await với một class để thực hiện method then(), cách viết này sẽ rất hữu dụng cho viết thư viện, v.v. Hi vọng bài viết đã giúp ích được các bạn.