Top 5 sai lầm mà các nhà phát triển Node mắc phải

Node là một nền tảng tuyệt vời để viết phụ trợ. Ngoại trừ khi bạn không nhận được những điều đúng đắn.


Tùy thuộc vào phía nào của hàng rào bạn xảy ra, Node là điều tốt nhất hoặc tồi tệ nhất xảy ra với thế giới Phát triển Web. Nhưng dù có ý kiến ​​gì đi nữa, ở đó, không có gì phải bàn cãi về sự phổ biến của Node. Nó bắn lên theo cách phổ biến nhanh hơn bất kỳ ai mong đợi, ngay cả người tạo ra nó (ông nói như vậy một cách bi quan phỏng vấn)!

Khi viết, nó là nền tảng mặc định để bắt đầu các ứng dụng mới, mà tôi thừa nhận thường là kết quả của tâm lý bầy đàn, nhưng hiệu quả ròng là có nhiều việc làm hơn, nhiều tiền hơn và các dự án thú vị hơn trong Node so với các ngôn ngữ kịch bản truyền thống khác.

Thật không may, một điều đáng tiếc là khi ai đó đề nghị tôi giới thiệu cho họ một ngăn xếp khởi đầu để phát triển web hoặc các sản phẩm khởi động mới, Node là đề xuất số 1 của tôi mặc dù tôi đã thành thạo PHP và Laravel.

Nếu tôi có thể được phép tiếp tục câu chuyện một chút (mà tôi sẽ là vì tôi là người viết?), Những người ghét Node có một điểm khi họ nói rằng ngăn xếp web yêu thích của họ có thể làm những việc giống như Node, nhưng Các ngược lại cũng đúng. Và sau đó, có những thứ lập trình và sự kiện không đồng bộ, được đưa vào Node từ ngày 1, và các hệ sinh thái khác hiện đang cố gắng sao chép một cách tuyệt vọng.

Ngày nay chúng ta có các tùy chọn không đồng bộ trong PHP và Python, nhưng thật không may, cốt lõi của các thư viện phổ biến hiện có hoàn toàn đồng bộ, do đó, nó gần như giống như bạn đang chiến đấu chống lại hệ thống. Nhưng dù sao, đủ rầm rộ cho một ngày. ��

Vì vậy, nếu bạn là một nhà phát triển Node (người mới bắt đầu hoặc quen thuộc), thì có lẽ bạn đã phạm phải một trong những sai lầm lớn này ảnh hưởng tiêu cực đến ứng dụng của bạn. Có thể là do bạn không quen với một cách cụ thể để làm mọi thứ tốt hơn trong Node, hoặc có thể nó chỉ đơn giản là thói quen mà bạn đã mang theo từ một số hệ sinh thái khác.

Không tôn trọng vòng lặp sự kiện

Khi một người di chuyển đến Node, một phần là do họ đã nghe những câu chuyện về cách LinkedIn mở rộng quy mô bằng Node hoặc họ đã thấy các điểm chuẩn hiển thị Node chạy vòng tròn quanh PHP, Ruby, v.v. khi nói đến việc phục vụ các yêu cầu mỗi giây hoặc xử lý kết nối ổ cắm mở.

Vì vậy, họ xây dựng ứng dụng của mình, mong đợi thời gian phản hồi bùng nổ giống như họ mơ ước – ngoại trừ việc không có gì gần với nó xảy ra.

Một trong những lý do chính cho việc này là không hiểu đúng về vòng lặp sự kiện. Hãy xem xét đoạn mã sau lấy một bộ sách từ cơ sở dữ liệu và sau đó sắp xếp chúng theo tổng số trang:

db.L Library.get (libraryId, hàm (err, library) {
hãy để sách = library.books;
Books.sort (hàm (a, b) {
trả lại a.pages < b.page? -1: 1
});
});

Tôi đồng ý rằng mã này không có bất cứ điều gì với mảng sách được sắp xếp, nhưng đó không phải là điểm ở đây. Vấn đề là một mã trông ngây thơ như vậy là đủ để làm nổ tung vòng lặp sự kiện ngay khi bạn bắt đầu giao dịch với một số lượng sách không hề nhỏ.

Lý do là vòng lặp sự kiện có nghĩa là thực hiện I / O không chặn. Một ví dụ điển hình là một người đóng gói pizza tại một cửa hàng pizza – người chuyên cắt pizza, gấp nắp vào hộp giao hàng, đặt pizza vào, gắn nhãn đúng và đẩy nó cho người giao hàng.

Thật tuyệt phải không? Giống như nút!

Nguồn: stackoverflow.com

Nhưng hãy xem xét những gì sẽ xảy ra nếu người này cũng cần trộn, chuẩn bị và đóng gói các gia vị. Tùy thuộc vào mức độ phức tạp của quy trình, tỷ lệ đóng gói bánh pizza sẽ giảm xuống còn một phần ba, hoặc thậm chí có thể dừng lại hoàn toàn.

Đây là ý nghĩa của chúng tôi đối với các nhiệm vụ là chặn chặn chặn – miễn là Node đơn giản phải truyền thông tin xung quanh, đó là lựa chọn tốt nhất và rất nhanh, nhưng ngay khi cần thực hiện một số tính toán mở rộng, nó sẽ dừng và mọi thứ khác phải chờ. Điều này xảy ra vì vòng lặp sự kiện là một luồng đơn (chi tiết hơn đây.)

Vì vậy, don lồng thực hiện các phép tính trong vòng lặp sự kiện, bất kể chúng quan trọng như thế nào. Ý tôi là, thêm số và lấy trung bình là tốt, nhưng bộ dữ liệu lớn sẽ khiến ứng dụng Node của bạn thu thập dữ liệu.

Hy vọng rằng mã async sẽ hợp tác

Hãy xem xét ví dụ Node rất đơn giản này để đọc dữ liệu từ một tệp và hiển thị nó:

const fs = Yêu cầu (‘fs’);

hãy để nội dung = fs.readFile (‘secret.txt’, (err, data) => {
trả lại dữ liệu;
});

console.log (‘Nội dung tệp là:’);
console.log (nội dung);

Tiếp xúc với các ngôn ngữ cổ điển (như PHP, Python, Perl, Ruby, C ++, v.v.) sẽ giúp bạn áp dụng ý thức chung là sau khi mã này chạy, nội dung biến sẽ có nội dung của tệp. Nhưng ở đây, những gì xảy ra khi bạn thực sự thực thi mã:

Chúng tôi nhận được không xác định (). Đó là vì trong khi bạn có thể quan tâm sâu sắc đến Node, thì bản chất không đồng bộ của nó không quan tâm đến bạn (nó có nghĩa là một trò đùa! Xin đừng lừa đảo những bình luận ghét thư rác ở đây). Công việc của chúng tôi là hiểu bản chất không đồng bộ của nó và làm việc với nó. readFile () là một hàm không đồng bộ, có nghĩa là ngay khi nó được gọi, vòng lặp sự kiện Node chuyển công việc đến thành phần hệ thống tập tin và tiếp tục.

Nó sẽ trở lại chức năng sau khi tệp đã được đọc, nhưng vào thời điểm đó, nội dung được xử lý như một biến chưa được khởi tạo và do đó chứa không xác định. Cách chính xác là xử lý dữ liệu tệp bên trong hàm gọi lại, nhưng tôi có thể đi sâu vào chi tiết hơn vì đây không phải là một Nút hướng dẫn. ��

Gọi lại mà gọi lại gọi lại gọi lại mà gọi . . .

JavaScript gần với lập trình chức năng hơn bất kỳ ngôn ngữ chính, cũ nào khác (thực tế, tất cả đã nói và đã làm, đó là sở thích của tôi khi nói đến thiết kế hướng đối tượng và các khả năng chức năng – Tôi đặt nó lên trên Python, PHP, Perl, Java và ngay cả Ruby khi viết mã thú vị trên mạng).

Đó là, các chức năng có được nhiều quyền công dân hơn so với các ngôn ngữ khác. Kết hợp điều này với thực tế là mã không đồng bộ hoạt động bằng cách cung cấp cho bạn chức năng gọi lại và chúng tôi kết thúc với một công thức cho thảm họa được gọi là Địa ngục gọi lại.

Ở đây, một số mẫu mã Electron tôi đã gặp trên Quora. Bạn nghĩ nó làm gì?

tùy chọn var;

yêu cầu (‘electron’). app.once (
‘Sẵn sàng’,

chức năng () {

tùy chọn = {
khung: sai,
chiều cao: 768,
chiều rộng: 1024,
x: 0,
y: 0
};

tùy chọn.BrowerWindow = Yêu cầu (‘electron’). BrowserWindow;
tùy chọn.browserWindow = tùy chọn mới.BrowerWindow (tùy chọn);
tùy chọn.browserWindow.loadURL (‘http://electron.atom.io’);
tùy chọn.browserWindow.webContents.once (
‘đã dừng tải’,

chức năng () {
tùy chọn.browserWindow.capturePage (
tùy chọn,

hàm (dữ liệu) {
yêu cầu (‘fs’). writeFileSync (
‘/tmp/screenCapture.testExampleJs.browser..png’,
dữ liệu.toPng ()
);

process.exit (0);
}
);
}
);
}
);

Nếu bạn gặp khó khăn, hãy tham gia câu lạc bộ!

Các chức năng bên trong các chức năng bên trong các chức năng rất khó đọc và rất khó để suy luận, đó là lý do tại sao nó được gọi là Hell callback hell. (Tôi cho rằng Địa ngục là một nơi khó hiểu để thoát ra!). Trong khi kỹ thuật này hoạt động, bạn đang làm cho mã của mình trở thành bằng chứng trong tương lai từ bất kỳ nỗ lực nào trong việc hiểu và bảo trì.

Có nhiều cách để tránh địa ngục gọi lại, bao gồm HứaPhần mở rộng phản ứng.

Không sử dụng tất cả các lõi CPU

Bộ xử lý hiện đại có một số lõi – 2, 4, 8, 16, 32. . . con số tiếp tục leo.

Nhưng đây không phải là điều mà người tạo ra Node đã nghĩ đến khi phát hành Node. Kết quả là, Node là một luồng đơn, có nghĩa là nó chạy bên trong một luồng đơn (hoặc quá trình, nếu bạn muốn gọi nó như vậy, mặc dù chúng không giống nhau), chỉ sử dụng một lõi CPU.

Điều đó có nghĩa là nếu bạn đã học Node từ các hướng dẫn, bạn bè và các đoạn mã trôi nổi xung quanh và ứng dụng của bạn được triển khai trên máy chủ 8 lõi, bạn đã lãng phí 7/8 sức mạnh xử lý có sẵn!

Không cần phải nói, nó rất lãng phí. Nếu bạn đi theo con đường này, cuối cùng bạn sẽ trả tiền cho tám máy chủ khi bạn chỉ cần một máy chủ. Đó là, chi 16.000 đô la mỗi tháng khi 2.000 đô la sẽ làm (mất tiền luôn đau, phải không?). Tất cả điều này, khi giải pháp khá đơn giản: sử dụng cụm mô-đun.

Tôi có thể đi sâu vào tất cả các chi tiết ở đây, nhưng đó là một kỹ thuật đơn giản để phát hiện có bao nhiêu lõi máy hiện tại, và sau đó khởi chạy nhiều phiên bản Node đó. Khi lỗi được phát hiện, cá thể được khởi động lại. Đây là cách đơn giản để thực hiện (hướng dẫn đây):

cụm var = Yêu cầu (‘cụm’);

if (cluster.isMaster) {
var numWorkers = Yêu cầu (‘os’). cpus (). length;

console.log (‘Thiết lập cụm chính’ + numWorkers + ‘worker …’);

cho (var i = 0; i < numWorkers; i ++) {
cluster.fork ();
}

cluster.on (‘trực tuyến’, hàm (worker) {
console.log (‘Công nhân’ + worker. process.pid + ‘đang trực tuyến’);
});

cluster.on (‘exit’, hàm (worker, code, signal) {
console.log (‘Công nhân’ + worker. process.pid + ‘đã chết với mã:’ + code + ‘và signal:’ + signal);
console.log (‘Bắt đầu một công nhân mới’);
cluster.fork ();
});
} khác {
var app = quiries (‘express’) ();
app.all (‘/ *’, function (req, res) {res.send (‘process’ + process.pid + ‘nói xin chào!’). end ();})

máy chủ var = app.listen (8000, hàm () {
console.log (‘Process’ + process.pid + ‘đang lắng nghe tất cả các yêu cầu đến’);
});
}

Như bạn có thể thấy, cluster.fork () thực hiện phép thuật và phần còn lại chỉ đơn giản là lắng nghe một vài sự kiện cụm cần thiết và thực hiện việc dọn dẹp cần thiết.

Không sử dụng TypeScript

Được rồi, nó không phải là một lỗi, như vậy, và rất nhiều ứng dụng Node đã và đang được viết mà không có TypeScript.

Điều đó nói rằng, TypeScript mang đến sự đảm bảo và an tâm rằng Node luôn cần thiết và trong mắt tôi, thật sai lầm nếu bạn đang phát triển cho Node vào năm 2019 và không sử dụng TypeScript (đặc biệt là khi A (Angular) trong ngăn xếp MEAN di chuyển đến TypeScript từ lâu).

Quá trình chuyển đổi diễn ra nhẹ nhàng và TypeScript gần như chính xác như JavaScript mà bạn biết, với sự chắc chắn của các loại, ES6 và một vài kiểm tra khác được đưa vào:

// /lib/controllers/crmControll.ts
nhập * dưới dạng cầy mangut từ ‘cầy mangut’;
nhập {ContactSchema} từ ‘../models/crmModel’;
nhập {Yêu cầu, Phản hồi} từ ‘express’;

const Liên hệ = mongoose.model (‘Liên hệ’, ContactSchema);
lớp xuất ContactControll {

công khai addNewContact (req: Request, res: Feedback) {
hãy để newContact = new Liên hệ (req.body);

newContact.save ((err, contact) => {
nếu (lỗi) {
res.send (err);
}
res.json (liên hệ);
});
}

Tôi khuyên bạn nên kiểm tra cái này tốt và thân thiện Hướng dẫn TypeScript.

Phần kết luận

Node rất ấn tượng, nhưng nó không phải là không có vấn đề (nhiều?). Điều đó nói rằng, điều này áp dụng cho tất cả các công nghệ ngoài kia, mới và cũ và chúng tôi sẽ làm tốt hơn để hiểu Node và làm việc với nó.

Tôi hy vọng năm mẹo này sẽ giúp bạn không bị hút vào hố sâu của các lỗi lâu năm và các vấn đề về hiệu suất. Nếu tôi bỏ lỡ điều gì đó thú vị, xin vui lòng cho tôi biết, và tôi sẽ hạnh phúc hơn (thực tế, rất biết ơn!) Để đưa chúng vào bài viết. ��

Jeffrey Wilson Administrator
Sorry! The Author has not filled his profile.
follow me
    Like this post? Please share to your friends:
    Adblock
    detector
    map