5 ข้อผิดพลาดที่นักพัฒนาโหนดทำ

โหนดเป็นแพลตฟอร์มที่ยอดเยี่ยมสำหรับการเขียนแบ็กเอนด์ ยกเว้นเมื่อคุณไม่ได้สิ่งที่ถูกต้อง.


ขึ้นอยู่กับว่าคุณอยู่ด้านใดของรั้ว Node เป็นสิ่งที่ดีที่สุดหรือเลวร้ายที่สุดที่เกิดขึ้นกับโลกการพัฒนาเว็บ แต่ความคิดเห็นแม้ว่าจะไม่มีการโต้เถียงความนิยมของโหนด มันสร้างความนิยมได้เร็วกว่าที่ใคร ๆ คาดคิดแม้แต่ผู้สร้างมัน (เขาพูดอย่างนั้นในแง่ร้าย) สัมภาษณ์)!

มันเป็นแพลตฟอร์มเริ่มต้นสำหรับการเริ่มต้นแอปใหม่ซึ่งฉันยอมรับว่าเป็นผลมาจากความคิดของฝูง แต่ผลกระทบสุทธิคือมีงานมากขึ้นเงินมากขึ้นและโครงการที่น่าตื่นเต้นใน Node กว่าในภาษาสคริปต์แบบดั้งเดิมอื่น ๆ.

โชคไม่ดีที่เมื่อมีคนขอให้ฉันแนะนำสแต็กเริ่มต้นสำหรับการพัฒนาเว็บหรือผลิตภัณฑ์เริ่มต้นใหม่โหนดเป็นคำแนะนำอันดับ 1 ของฉันแม้ว่าฉันจะมีความเชี่ยวชาญใน PHP และ Laravel.

ถ้าฉันอาจได้รับอนุญาตให้พูดจาโผงผางต่อไปอีกนิด (ซึ่งฉันจะเป็นเพราะฉันเป็นคนเขียน?), ผู้เกลียดชังโหนดมีจุดเมื่อพวกเขาบอกว่าเว็บสแต็คโปรดของพวกเขาสามารถทำสิ่งต่าง ๆ ได้เช่นเดียวกับโหนด การสนทนาก็เป็นจริงเช่นกัน และจากนั้นก็มีการเขียนโปรแกรมและกิจกรรม async ที่อบเข้าสู่โหนดจากวันที่ 1 และระบบนิเวศอื่น ๆ กำลังพยายามที่จะคัดลอก.

วันนี้เรามีตัวเลือก async ใน PHP และ Python แต่น่าเสียดายที่แกนหลักของไลบรารีที่มีอยู่และเป็นที่นิยมนั้นมีการซิงโครนัสอย่างหมดจดดังนั้นมันเกือบจะเหมือนกับที่คุณต่อสู้กับระบบ แต่อย่างไรก็ตามการคุยโวมากพอสำหรับวันเดียว ��

ดังนั้นหากคุณเป็นนักพัฒนาโหนด (ผู้เริ่มต้นหรือคุ้นเคย) อาจเป็นไปได้ว่าคุณกำลังทำผิดพลาดครั้งใหญ่ข้อหนึ่งที่ส่งผลเสียต่อแอปพลิเคชันของคุณ อาจเป็นเพราะคุณไม่คุ้นเคยกับวิธีการทำสิ่งที่ดีกว่าในโหนดหรืออาจเป็นเพียงแค่นิสัยที่คุณเคยทำมาจากระบบนิเวศอื่น ๆ.

ไม่เคารพห่วงเหตุการณ์

เมื่อมีคนย้ายไปที่โหนดส่วนหนึ่งเป็นเพราะพวกเขาเคยได้ยินเรื่องราวของ LinkedIn ในการปรับขนาดการใช้ Node หรือพวกเขาเคยเห็นมาตรฐานที่แสดงให้เห็นว่า Node ใช้งานวงกลมรอบ PHP, Ruby และอื่น ๆ เมื่อมาถึงการให้บริการตามคำขอ เปิดการเชื่อมต่อซ็อกเก็ต.

ดังนั้นพวกเขาจึงสร้างแอพโดยคาดหวังว่าจะได้รับการตอบสนองอย่างระเบิดเหมือนที่พวกเขาเคยฝันยกเว้นว่าไม่มีอะไรเกิดขึ้น.

หนึ่งในเหตุผลสำคัญสำหรับเรื่องนี้คือการไม่เข้าใจเหตุการณ์วงอย่างถูกต้อง พิจารณารหัสต่อไปนี้ที่ได้รับชุดหนังสือจากฐานข้อมูลแล้วเรียงลำดับตามจำนวนหน้าทั้งหมด:

db.Library.get (libraryId, ฟังก์ชัน (err, library) {
ให้หนังสือ = library.books;
books.sort (ฟังก์ชั่น (a, b) {
กลับมา < b.pages -1: 1
});
});

ฉันยอมรับว่ารหัสนี้ไม่ได้ทำอะไรกับอาร์เรย์หนังสือที่เรียงลำดับ แต่นั่นไม่ใช่จุดที่นี่ ประเด็นก็คือรหัสที่ดูไร้เดียงสานั้นเพียงพอที่จะทำให้เหตุการณ์เกิดขึ้นทันทีที่คุณเริ่มติดต่อกับหนังสือที่ไม่สำคัญ.

เหตุผลก็คือการวนรอบเหตุการณ์นั้นหมายถึงทำการปิดกั้น I / O ตัวอย่างที่ดีคือของผู้แบ่งบรรจุพิซซ่าที่ร้านพิซซ่าคนที่มีความเชี่ยวชาญในการตัดพิซซ่าพับฝาครอบลงในกล่องส่งมอบวางพิซซ่าเข้าแนบป้ายด้านขวาและผลักมันไปที่คนส่งของ.

น่าอัศจรรย์ใช่มั้ย เช่นเดียวกับโหนด!

ที่มา: stackoverflow.com

แต่ให้พิจารณาว่าจะเกิดอะไรขึ้นถ้าบุคคลนี้ต้องการผสมปรุงและทำเครื่องปรุงรสด้วย ขึ้นอยู่กับความซับซ้อนของกระบวนการคืออัตราการบรรจุพิซซ่าจะลดลงเหลือหนึ่งในสามหรืออาจหยุดลง.

นี่คือสิ่งที่เราหมายถึงโดยงานที่ “บล็อก” – ตราบใดที่โหนดต้องส่งข้อมูลไปรอบ ๆ มันเป็นตัวเลือกที่ดีที่สุดอย่างรวดเร็วและสมบูรณ์แบบ แต่ทันทีที่มันต้องทำการคำนวณอย่างละเอียดหยุดและทุกอย่าง อื่นต้องรอ สิ่งนี้เกิดขึ้นเนื่องจากการวนรอบเหตุการณ์เป็นเธรดเดี่ยว (รายละเอียดเพิ่มเติม ที่นี่.)

ดังนั้นอย่าทำการคำนวณภายในลูปเหตุการณ์ไม่ว่าจะสำคัญแค่ไหน ฉันหมายถึงการเพิ่มตัวเลขและรับค่าเฉลี่ยนั้นดี แต่ชุดข้อมูลขนาดใหญ่จะทำให้แอป Node ของคุณรวบรวมข้อมูล.

หวังว่ารหัส async จะให้ความร่วมมือ

ลองพิจารณาตัวอย่างโหนดง่ายๆนี้ที่อ่านข้อมูลจากไฟล์และแสดง:

const fs = ต้องการ (‘fs’);

ให้ content = fs.readFile (‘secret.txt’, (err, data) => {
ส่งคืนข้อมูล
});

console.log (‘เนื้อหาไฟล์คือ:’);
console.log (เนื้อหา);

สัมผัสกับภาษาคลาสสิก (เช่น PHP, Python, Perl, Ruby, C ++ ฯลฯ ) จะช่วยให้คุณใช้สามัญสำนึกว่าหลังจากที่โค้ดนี้รันแล้วเนื้อหาตัวแปรจะมีเนื้อหาของไฟล์ แต่นี่คือสิ่งที่เกิดขึ้นเมื่อคุณเรียกใช้รหัสจริง:

เราได้รับไม่ได้กำหนด () นั่นเป็นเพราะในขณะที่คุณอาจสนใจเรื่อง Node อย่างลึกซึ้งลักษณะของ async ไม่ได้สนใจคุณ (มันควรจะเป็นเรื่องตลก! โปรดอย่าสแปมความคิดเห็นที่เกลียดที่นี่��) งานของเราคือการเข้าใจธรรมชาติของ async และทำงานกับมัน readFile () เป็นฟังก์ชั่นแบบอะซิงโครนัสซึ่งหมายถึงทันทีที่มันถูกเรียกใช้เหตุการณ์วงรอบโหนดจะส่งผ่านงานไปยังองค์ประกอบของระบบไฟล์และย้ายไป.

มันจะกลับไปที่ฟังก์ชั่นในภายหลังเมื่ออ่านไฟล์ แต่เนื้อหาในเวลานั้นถือว่าเป็นตัวแปรที่ไม่มีการกำหนดค่าเริ่มต้น วิธีที่ถูกต้องคือการประมวลผลข้อมูลไฟล์ภายในฟังก์ชั่นการโทรกลับ แต่ฉันไม่สามารถดูรายละเอียดเพิ่มเติมได้เนื่องจากนี่ไม่ใช่ บทช่วยสอนเกี่ยวกับโหนด. ��

โทรกลับที่โทรกลับที่โทรกลับโทรที่ . . .

จาวาสคริปต์นั้นใกล้เคียงกับการเขียนโปรแกรมการใช้งานมากกว่าภาษาหลักอื่น ๆ (อันที่จริงทุกคนพูดและทำมันเป็นสิ่งที่ฉันโปรดปรานเมื่อพูดถึงการออกแบบเชิงวัตถุและความสามารถในการใช้งาน – ฉันวางไว้เหนือ Python, PHP, Perl, Java และ แม้แต่ Ruby เมื่อพูดถึงการเขียนโค้ด“ สนุกสนาน”).

นั่นคือฟังก์ชั่นได้รับสิทธิพลเมืองมากกว่าที่พวกเขาทำในภาษาอื่น จับคู่สิ่งนี้กับความจริงที่ว่าโค้ดอะซิงโครนัสทำงานได้โดยให้ฟังก์ชั่นการโทรกลับและคุณก็จบลงด้วยสูตรสำหรับความหายนะที่เรียกว่าคอลแบ็คนรก.

นี่คือตัวอย่างรหัสอิเล็กตรอนที่ฉันพบใน Quora คุณคิดว่ามันทำอะไร?

ตัวเลือก var;

ต้อง (อิเล็กตรอน). app.once (
‘พร้อม’,

ฟังก์ชั่น () {

ตัวเลือก = {
เฟรม: เท็จ,
ความสูง: 768,
ความกว้าง: 1024,
x: 0,
y: 0
};

options.BrowserWindow = ต้องการ (‘อิเล็กตรอน’) BrowserWindow;
options.browserWindow = ตัวเลือกใหม่.BrowserWindow (ตัวเลือก);
options.browserWindow.loadURL ( ‘http://electron.atom.io’);
options.browserWindow.webContents.once (
‘ไม่หยุดโหลด’,

ฟังก์ชั่น () {
options.browserWindow.capturePage (
ตัวเลือก,

ฟังก์ชั่น (ข้อมูล) {
ต้องใช้ (FS). writeFileSync (
‘/tmp/screenCapture.testExampleJs.browser..png’,
data.toPng ()
);

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

หากคุณกำลังมีปัญหาให้เข้าร่วมคลับ!

ฟังก์ชั่นภายในฟังก์ชั่นภายในฟังก์ชั่นนั้นยากต่อการอ่านและยากที่จะเข้าใจซึ่งเป็นสาเหตุที่มันถูกเรียกว่า “นรกโทรกลับ” (ฉันคิดว่านรกเป็นสถานที่ที่ทำให้สับสนได้!) ในขณะที่เทคนิคนี้ใช้งานได้คุณกำลังสร้างรหัสของคุณในอนาคตพิสูจน์จากความพยายามที่เข้าใจและบำรุงรักษา.

มีหลายวิธีที่จะหลีกเลี่ยงการโทรกลับนรกรวมถึง สัญญา และ ส่วนขยายปฏิกิริยา.

ไม่ได้ใช้คอร์ CPU ทั้งหมด

โปรเซสเซอร์สมัยใหม่มีหลายคอร์ – 2, 4, 8, 16, 32 . . จำนวนยังคงปีนขึ้นไป.

แต่นี่ไม่ใช่สิ่งที่ผู้สร้าง Node มีอยู่ในใจเมื่อเขาปล่อย Node เป็นผลให้โหนดเป็นแบบเธรดเดี่ยวซึ่งหมายความว่ามันทำงานภายในเธรดเดียว (หรือกระบวนการถ้าคุณต้องการเรียกมันว่าแม้ว่าพวกเขาจะไม่เหมือนกัน) ใช้ซีพียูแกนเดียวเท่านั้น.

นั่นหมายความว่าถ้าคุณเรียนรู้โหนดจากบทช่วยสอนและเพื่อน ๆ และตัวอย่างโค้ดที่ลอยอยู่รอบ ๆ และให้แอปของคุณติดตั้งบนเซิร์ฟเวอร์ 8-core คุณจะสูญเสียพลังการประมวลผลถึง 7/8!

ไม่ต้องพูดถึงมันเป็นเรื่องใหญ่เสียเปล่า หากคุณปฏิบัติตามเส้นทางนี้คุณจะต้องชำระเงินให้กับเซิร์ฟเวอร์แปดแห่งเมื่อคุณต้องการเพียงเซิร์ฟเวอร์เดียว นั่นคือใช้จ่าย $ 16,000 ต่อเดือนเมื่อทำ $ 2,000 (สูญเสียเงินเจ็บเสมอใช่ไหม?) ทั้งหมดนี้เมื่อวิธีการแก้ปัญหาค่อนข้างง่าย: ใช้ กลุ่ม โมดูล.

ฉันไม่สามารถเข้าไปดูรายละเอียดทั้งหมดได้ที่นี่ แต่มันเป็นเทคนิคง่ายๆในการตรวจสอบว่ามีเครื่องประมวลผลในปัจจุบันจำนวนแกนประมวลผลใดบ้างแล้วเปิดใช้งานอินสแตนซ์โหนดจำนวนมาก เมื่อตรวจพบข้อผิดพลาดอินสแตนซ์จะถูกรีสตาร์ท นี่คือความง่ายในการใช้งาน (บทช่วยสอน ที่นี่):

var cluster = require (‘cluster’);

if (cluster.isMaster) {
var numWorkers = ต้องการ (‘os’). cpus (). length;

console.log (‘การตั้งค่าคลัสเตอร์หลัก’ + numWorkers + ‘คนทำงาน … ‘);

สำหรับ (var i = 0; i < numWorkers; ฉัน ++) {
cluster.fork ();
}

cluster.on (‘ออนไลน์’ ฟังก์ชัน (ผู้ปฏิบัติงาน) {
console.log (‘ผู้ทำงาน’ + คนงาน process.pid + ‘ออนไลน์’);
});

cluster.on (‘exit’, ฟังก์ชัน (ผู้ปฏิบัติงาน, รหัส, สัญญาณ) {
console.log (‘คนทำงาน’ + คนงาน process.pid + ‘เสียชีวิตด้วยรหัส:’ + code + ‘และสัญญาณ:’ + สัญญาณ);
console.log (‘การเริ่มงานใหม่’);
cluster.fork ();
});
} อื่น {
แอป var = ต้องการ (‘ด่วน’) ();
app.all (‘/ *’, ฟังก์ชั่น (req, res) {res.send (‘กระบวนการ’ + process.pid + ‘พูดว่า hello!’) end ();})

var server = app.listen (8000, ฟังก์ชัน () {
console.log (‘กระบวนการ’ + process.pid + ‘กำลังรับฟังคำขอที่เข้ามาทั้งหมด’);
});
}

อย่างที่คุณเห็น cluster.fork () ทำเวทมนต์และสิ่งที่เหลือก็แค่ฟังเหตุการณ์สำคัญสองสามอย่างและทำการล้างข้อมูลที่จำเป็น.

ไม่ได้ใช้ TypeScript

โอเคมันไม่ใช่ความผิดพลาดเช่นนั้นและมีแอปพลิเคชั่นโหนดมากมายที่ถูกเขียนขึ้นโดยไม่มี TypeScript.

TypeScript ให้การรับรองและความอุ่นใจที่ Node ต้องการเสมอและในสายตาของฉันมันเป็นความผิดพลาดถ้าคุณพัฒนา Node ในปี 2019 และไม่ใช้ TypeScript (โดยเฉพาะเมื่อ A (Angular) ในกอง MEAN เคลื่อนไหว เป็น TypeScript เมื่อนานมาแล้ว).

การเปลี่ยนแปลงนั้นอ่อนโยนและ TypeScript นั้นเกือบจะเหมือนกับจาวาสคริปต์ที่คุณรู้จักอย่างแน่นอนด้วยการรับรองประเภท ES6 และการตรวจสอบอื่น ๆ

// /lib/controllers/crmController.ts
นำเข้า * เป็นพังพอนจาก ‘พังพอน’;
นำเข้า {ContactSchema} จาก ‘../models/crmModel’;
นำเข้า {Request, Response} จาก ‘express’;

ติดต่อ const = mongoose.model (‘ติดต่อ’, ContactSchema);
ส่งออกคลาส ContactController {

สาธารณะ addNewContact (คำขอ: คำขอ, res: การตอบสนอง) {
ให้ newContact = ผู้ติดต่อใหม่ (req.body);

newContact.save ((ข้อผิดพลาดผู้ติดต่อ) => {
(ถ้าผิดพลาด) {
res.send (ผิดพลาด);
}
res.json (ติดต่อ);
});
}

ฉันขอแนะนำให้ตรวจสอบสิ่งนี้ดีและเป็นมิตร แบบฝึกหัด TypeScript.

ข้อสรุป

โหนดเป็นที่น่าประทับใจ แต่ก็ไม่ได้โดยไม่มีปัญหา (มาก?) ที่กล่าวมานี้ใช้กับเทคโนโลยีทั้งหมดที่มีทั้งเก่าและใหม่และเราจะทำดีกว่าที่จะเข้าใจโหนดและทำงานกับมัน.

ฉันหวังว่าเคล็ดลับห้าข้อนี้จะป้องกันคุณจากการถูกดูดเข้าไปในบ่อน้ำมันของแมลงที่ยืนต้นและปัญหาด้านประสิทธิภาพ หากฉันพลาดสิ่งที่น่าสนใจโปรดแจ้งให้เราทราบและฉันจะมีความสุขมาก (จริง ๆ แล้วขอบคุณมาก!) ที่จะรวมไว้ในบทความ ��

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