Vấn đề đồng bộ dữ liệu với nodejs
-
Ai cũng biết bất đồng bộ là ưu thế tốc độ với nodejs nhưng mà với beginner như mình thì cũng khá căng thẳng.
Đại loại mình có 1 func để validate chút dữ liệu và mình cần nó return true hoặc false để xác thực đầu vào như thế này ạ:validateToken: function(req, res, next) { var token = req.body.token; if (!token) { res.send({ code: 400, error: res.__('api.auth.error.tokenrequired') }); } else { // Set DB AuthModel.setDB(req.db); // Check token AuthModel.getlist(function (err, records) { if (records.length == 0) { res.send({ code: 400, error: res.__('api.auth.error.tokeninvalid') }); } else { return true; } }, { token: token }); } return false; }
Mình test thử mà nó chưa chạy đoạn if else đã chạy đến đoạn cuối và return false rùi.
E có áp dùng module sync nhưng chưa bít cách code lắm!.
Bạn nào biết chỉ giáo mình chút với ạ.
Thanks all!
-
Chơi với
Async
thì code cũng phải được thiết kế dạng async bạn ạTức là thay vì sử dụng
return
thì bạn cần phải gọi hàmcallback
khi thực hiện xong 1 tác vụ async.Bạn đọc thêm các bài sau đây để hiểu bản chất hơn, tránh gặp phải những lỗi tương tự:
https://techmaster.vn/posts/33416/hoc-lap-trinh-web-javascript
https://techmaster.vn/posts/33344/lap-trinh-nodejs-co-ban-den-nang-cao
-
Mình nhớ @Rik-Ky có 1 bài rất hay về không đồng bộ, nhưng tìm không ra. Sẽ rất tuyệt nếu như bạn được đọc bài viết đó. Ko biết có bác nào có link ko ?
-
@Tieu-dang-van bạn nên dùng module Async để làm việc với cơ sở dữ liệu trong nodejs.
-
@Vũ rảnh Tùng sẽ lục cái DB xem còn ko. Thanks
-
Mình cũng biết là phải áp dùng sync vào rùi nhưng mà thực tế chưa quan với câu cú của nodejs lắm nên chưa biết cách bố trí thế nào cho hợp lý và chuẩn.
Mọi ng có thể chỉ rõ hơn được không ạ?
Thanks all!
-
Là 1 routes
validateToken: function(req, res, next)
Thì sao lạireturn true, false
bạn.
Với format lại code đi kìa.
-
@Tieu-dang-van block code nào xác định phải đồng bộ thì cả block đó nên dùng đồng bộ.
Ví dụ đoạn code của bạn có vấn đề như sau :alidateToken: function(req, res, next) { var token = req.body.token; // block if else vì trả lại kết quả chậm hơn` return false `nên hàm alidateToken sẽ nhận giá trị false; if (!token) { res.send({ code: 400, error: res.__('api.auth.error.tokenrequired') }); } else { // Set DB AuthModel.setDB(req.db); // Check token AuthModel.getlist(function(err, records) { if (records.length == 0) { res.send({ code: 400, error: res.__('api.auth.error.tokeninvalid') }); } else { return true; // ~? } }, { token: token }); } return false; // trả về false cho alidateToken = > kết thúc khối lệnh alidateToken; , bên cạnh đó đoạn này sẽ là viết SAI nếu bạn đang dùng express để làm router điều hướng, trả về false sẽ khiến toàn bộ router của bạn bị loop redirect. }
Nodejs là bất đồng bộ (nhiều tác vụ chạy song song,), còn hầu hết các ngôn ngữ khác là đồng bộ. Với ngôn ngữ lập trình đồng bộ, block
if else
của bạn sẽ thực hiện hết rồi mới đếnreturn false
, với nodejs do thực hiện song song, tác vụ nào trả về kết quả trước sẽ được ưu tiên trước. Vì vậy code của bạn nếu muốn viết đúng phải dùng moduleasync
hoặcbluebird
hoặcQ
để áp chế cái bất đồng bộ của JS, hoặc ảo diệu nhất là dùngcallback hell
(nếu code đơn giản thì hell là heo thôi, còn code phức hợp thì welcome to the HELL<nodejs> ) . Do đó code của bạn nên viết lại như sau:var async = require('async'); //... stuff .. alidateToken: function(req, res, next) { var token = req.body.token; if (!token) { return res.send({ code: 400, error: res.__('api.auth.error.tokenrequired') }); } else { // toàn bộ block cần áp chế đồng bộ async.waterfall([ function(callback) { // Set DB AuthModel.setDB(req.db); // Check token AuthModel.getlist(function(err, records) { if (err) return callback(err,null); if (records.length == 0) { return callback(err,null); } else { return callback(null,true); } }, { token: token }); } ], function(err, result) { if (err) { return res.send({ code: 400, error: res.__('api.auth.error.tokeninvalid') }); }; return res.send({msg:'token is valid.'}) }); } //return false; // }
-
- Cái
validateToken
của bạn là một middleware thì bạn cầnreturn next()
hoặc trả về kết quả ngay và không cho phépnext
đến route đứng sau. - Trong
if else
của bạn, bạn không sử dụngreturn res.send({...})
nênvalidateToken
không dừng lại khires.send
đã chạy xong nênreturn false;
ở cuối cùng luôn chạy.
Bạn có thể thay
return false
thànhelse return false
để kiểm tra thử trước. Mình đang nghĩ vấn đề bạn gặp phải không phải vấn đề đồng bộ hay bất đồng bộ mà code chưa tối ưu. Hãy hạn chế sử dụng các thư viện async và kể cả ES6 promise hay mấy cái thứ đại loại như vậy, nó chỉ làm code của bạn thêm rối.Dừng lại 1 chút và đọc bài viết về callback này trước khi bạn tiếp tục code.
- Cái