มันเป็นการตัดสินใจโดยเจตนาหรือมีปัญหากับเบราว์เซอร์วันปัจจุบันของเราซึ่งจะแก้ไขในเวอร์ชันที่จะมาถึงหรือไม่?
มันเป็นการตัดสินใจโดยเจตนาหรือมีปัญหากับเบราว์เซอร์วันปัจจุบันของเราซึ่งจะแก้ไขในเวอร์ชันที่จะมาถึงหรือไม่?
คำตอบ:
JavaScript ไม่รองรับมัลติเธรดเนื่องจากล่าม JavaScript ในเบราว์เซอร์เป็นเธรดเดียว (AFAIK) แม้แต่ Google Chrome ก็ไม่ยอมให้จาวาสคริปต์ของเว็บเพจหนึ่ง ๆ ทำงานพร้อมกันเพราะจะทำให้เกิดปัญหาการทำงานพร้อมกันจำนวนมากในหน้าเว็บที่มีอยู่ Chrome ทั้งหมดทำแยกองค์ประกอบหลาย ๆ อย่าง (แท็บต่าง ๆ , ปลั๊กอิน, และอื่น ๆ ) เป็นกระบวนการแยกกัน แต่ฉันไม่สามารถจินตนาการหน้าเดียวที่มีมากกว่าหนึ่งเธรด JavaScript
อย่างไรก็ตามคุณสามารถใช้ตามที่แนะนำsetTimeout
เพื่อให้มีการจัดตารางเวลาและการเกิดพร้อมกัน "ปลอม" สิ่งนี้ทำให้เบราว์เซอร์สามารถควบคุมเธรดการแสดงผลได้อีกครั้งและเริ่มต้นโค้ด JavaScript ที่จัดหาให้setTimeout
หลังจากจำนวนมิลลิวินาทีที่กำหนด สิ่งนี้มีประโยชน์มากหากคุณต้องการให้วิวพอร์ต (สิ่งที่คุณเห็น) รีเฟรชในขณะดำเนินการกับมัน เพียงแค่วนลูปเช่นพิกัดและอัปเดตองค์ประกอบตามนั้นจะช่วยให้คุณเห็นตำแหน่งเริ่มต้นและจุดสิ้นสุดและไม่มีอะไรในระหว่าง
เราใช้ไลบรารีนามธรรมใน JavaScript ที่ทำให้เราสามารถสร้างกระบวนการและเธรดที่จัดการทั้งหมดโดยล่าม JavaScript เดียวกัน สิ่งนี้ทำให้เราสามารถดำเนินการในลักษณะต่อไปนี้:
สิ่งนี้อนุญาตให้รูปแบบการกำหนดเวลาและการปลอมตัวแบบขนานบางอย่างเริ่มต้นและหยุดเธรดและอื่น ๆ แต่จะไม่เป็นมัลติเธรดที่แท้จริง ฉันไม่คิดว่ามันจะถูกนำไปใช้ในภาษาของตัวเองเนื่องจากมัลติเธรดที่แท้จริงจะมีประโยชน์เฉพาะถ้าเบราว์เซอร์สามารถรันเธรดหน้าเดียวแบบมัลติเธรด (หรือมากกว่าหนึ่งคอร์) และปัญหาที่มีขนาดใหญ่กว่า กว่าความเป็นไปได้พิเศษ
สำหรับอนาคตของ JavaScript ให้ตรวจสอบสิ่งนี้: https://developer.mozilla.org/presentations/xtech2006/javascript/
JavaScript หลายเธรด (มีข้อ จำกัด ) อยู่ที่นี่ Google นำคนงานมาใช้สำหรับ Gears และคนงานกำลังรวมอยู่ใน HTML5 เบราว์เซอร์ส่วนใหญ่ได้เพิ่มการรองรับคุณสมบัตินี้แล้ว
มีการรับประกันความปลอดภัยของข้อมูลของเธรดเนื่องจากข้อมูลทั้งหมดที่สื่อสารไปยัง / จากผู้ปฏิบัติงานได้รับการจัดลำดับ / คัดลอก
สำหรับข้อมูลเพิ่มเติมอ่าน:
ตามเนื้อผ้า JS มีไว้สำหรับโค้ดสั้น ๆ ที่รันเร็ว หากคุณมีการคำนวณที่สำคัญเกิดขึ้นคุณทำมันบนเซิร์ฟเวอร์ - ความคิดของแอป JS + HTML ที่รันในเบราว์เซอร์ของคุณเป็นเวลานานในการทำสิ่งที่ไม่ใช่เรื่องไร้สาระเป็นเรื่องไร้สาระ
แน่นอนว่าตอนนี้เรามีสิ่งนั้นแล้ว แต่จะต้องใช้เวลาสักหน่อยก่อนที่เบราว์เซอร์จะทันซึ่งส่วนใหญ่ได้รับการออกแบบรอบ ๆ แบบเธรดเดียวและการเปลี่ยนแปลงที่ไม่ง่าย Google Gears มีปัญหาที่อาจเกิดขึ้นจำนวนมากโดยกำหนดให้การดำเนินการพื้นหลังนั้นแยก - ไม่มีการเปลี่ยนแปลง DOM (เนื่องจากไม่ปลอดภัยกับเธรด) ไม่มีการเข้าถึงวัตถุที่สร้างโดยเธรดหลัก (เหมือนกัน) ในขณะที่ข้อ จำกัด นี้น่าจะเป็นการออกแบบที่ใช้ประโยชน์ได้มากที่สุดในอนาคตอันใกล้ทั้งสองอย่างเพราะมันช่วยให้การออกแบบของเบราว์เซอร์ง่ายขึ้นและเพราะช่วยลดความเสี่ยงที่เกี่ยวข้องกับการอนุญาตให้ JS coders ที่ไม่มีประสบการณ์
@marcio :
เหตุใดจึงเป็นเหตุผลที่จะไม่ใช้มัลติเธรดใน Javascript โปรแกรมเมอร์สามารถทำสิ่งที่พวกเขาต้องการด้วยเครื่องมือที่พวกเขามี
ดังนั้นอย่าให้พวกเขามีเครื่องมือที่ง่ายต่อการใช้ผิดวัตถุประสงค์ที่เว็บไซต์อื่น ๆ ที่ฉันเปิดทุกแห่งจะล่มเบราว์เซอร์ของฉัน การใช้ความไร้เดียงสาของสิ่งนี้จะนำคุณเข้าสู่ดินแดนที่ทำให้ MS ปวดหัวจำนวนมากในระหว่างการพัฒนา IE7: ผู้เขียน add-on ที่เล่นอย่างรวดเร็วและหลวมด้วยรูปแบบการทำเกลียวทำให้เกิดข้อบกพร่องที่ซ่อนอยู่ . BAD หากคุณกำลังเขียนโปรแกรมเสริม ActiveX แบบหลายเธรดสำหรับ IE ฉันคิดว่ามันมาพร้อมกับอาณาเขต; ไม่ได้หมายความว่ามันจะต้องไปไกลกว่านั้นอีก
ฉันไม่ทราบเหตุผลของการตัดสินใจนี้ แต่ฉันรู้ว่าคุณสามารถจำลองประโยชน์ของการเขียนโปรแกรมแบบมัลติเธรดโดยใช้ setTimeout คุณสามารถให้ภาพลวงตาของกระบวนการหลายอย่างที่ทำสิ่งต่าง ๆ ในเวลาเดียวกัน แต่ในความเป็นจริงทุกอย่างเกิดขึ้นในหัวข้อเดียว
เพียงให้ฟังก์ชั่นของคุณทำงานเล็กน้อยจากนั้นโทรหาสิ่งที่ชอบ:
setTimeout(function () {
... do the rest of the work...
}, 0);
และสิ่งอื่น ๆ ที่ต้องทำ (เช่นอัปเดต UI, ภาพเคลื่อนไหว, ฯลฯ ) จะเกิดขึ้นเมื่อพวกเขามีโอกาส
loop
ภายในsetTimeout
แต่เห็นได้ชัดว่าไม่ได้ผล คุณทำอะไรแบบนั้นหรือว่าคุณแฮ็ค? ตัวอย่างจะเป็นสำหรับอาร์เรย์ 1000 องค์ประกอบผมคาดว่าจะใช้สองสำหรับลูปภายในสองsetTimeout
สายดังกล่าวว่าลูปแรกผ่านและพิมพ์องค์ประกอบลูปที่สองผ่านและบรรยากาศการพิมพ์0..499
500..999
คุณหมายถึงเพราะเหตุใดภาษาจึงไม่รองรับมัลติเธรดหรือทำไมเอนจิน JavaScript ในเบราว์เซอร์ไม่สนับสนุนการมัลติเธรด?
คำตอบสำหรับคำถามแรกคือ JavaScript ในเบราว์เซอร์นั้นมีวัตถุประสงค์เพื่อให้ทำงานในแซนด์บ็อกซ์และในวิธีที่เป็นอิสระจากเครื่อง / ระบบปฏิบัติการการเพิ่มการรองรับมัลติเธรดจะทำให้ภาษาซับซ้อนและผูกกับภาษามากเกินไป
Node.js 10.5+ รองรับเธรดผู้ปฏิบัติงานเป็นคุณลักษณะทดลอง (คุณสามารถใช้กับการเปิดใช้งาน--experimental- flag flag): https://nodejs.org/api/worker_threads.html
ดังนั้นกฎคือ:
เธรดผู้ปฏิบัติงานมีวัตถุประสงค์เพื่อเป็นเธรดที่มีอายุการใช้งานยาวนานซึ่งหมายความว่าคุณจะวางไข่เธรดพื้นหลังและสื่อสารกับมันผ่านการส่งข้อความ
มิฉะนั้นถ้าคุณจำเป็นต้องเรียกใช้งานโหลดซีพียูจำนวนมากด้วยฟังก์ชั่นที่ไม่ระบุชื่อคุณสามารถไปที่https://github.com/wilk/microjobไลบรารีขนาดเล็กที่สร้างขึ้นรอบเธรดผู้ทำงาน
เช่นเดียวกับด้าน b กล่าวว่าคำถามไม่ชัดเจน สมมติว่าคุณกำลังถามเกี่ยวกับการสนับสนุนมัลติเธรดในภาษา: เนื่องจากมันไม่จำเป็นสำหรับ 99.999% ของแอปพลิเคชันที่ทำงานในเบราว์เซอร์ในปัจจุบัน หากคุณต้องการจริงๆมีวิธีแก้ไขปัญหา (เช่นใช้ window.setTimeout)
โดยทั่วไปแล้วมัลติเธรดคือมากมากมากมากยากมาก (ฉันบอกว่ามันยากไหม) เพื่อให้ถูกต้องเว้นแต่คุณจะใส่ข้อ จำกัด เพิ่มเติม (เช่นการใช้ข้อมูลที่ไม่เปลี่ยนรูปเท่านั้น)
Intel ได้ทำการวิจัยโอเพนซอร์ซเกี่ยวกับการทำมัลติเธรดใน Javascript เมื่อเร็ว ๆ นี้ซึ่งได้เปิดตัวใน GDC 2012 นี่คือลิงค์สำหรับวิดีโอวิดีโอกลุ่มวิจัยใช้ OpenCL ซึ่งเน้นไปที่ชุด Intel Chip และ Windows OS เป็นหลัก โครงการมีชื่อรหัสว่า RiverTrail และรหัสนั้นมีอยู่ใน GitHub
ลิงค์ที่มีประโยชน์บางอย่าง:
ขณะนี้เบราว์เซอร์บางตัวรองรับการทำงานแบบมัลติเธรด ดังนั้นหากคุณต้องการให้คุณใช้ไลบรารีเฉพาะ ตัวอย่างเช่นดูวัสดุต่อไป:
https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers (สนับสนุนเธรดพื้นหลัง);
https://keithwhor.github.io/multithread.js/ (ห้องสมุด)
เป็นการนำไปใช้งานที่ไม่สนับสนุนการทำเธรดหลาย ปัจจุบัน Google Gears กำลังให้วิธีการใช้รูปแบบของการเกิดพร้อมกันบางรูปแบบโดยการดำเนินการกระบวนการภายนอก แต่ที่เกี่ยวกับมัน
เบราว์เซอร์ใหม่ที่ Google คาดว่าจะเปิดตัวในวันนี้ (Google Chrome) รันโค้ดบางส่วนพร้อมกันโดยแยกออกเป็นกระบวนการ
แน่นอนว่าภาษาแกนกลางสามารถให้การสนับสนุนเหมือนกับพูด Java แต่การสนับสนุนบางอย่างเช่นการทำงานพร้อมกันของ Erlang นั้นไม่มีที่ไหนใกล้ขอบฟ้า
Javascript เป็นภาษาแบบเธรดเดียว ซึ่งหมายความว่ามีการโทรหนึ่งครั้งและหนึ่งหน่วยความจำฮีป ตามที่คาดไว้มันรันโค้ดตามลำดับและต้องดำเนินการโค้ดให้เสร็จก่อนที่จะย้ายไปยังโค้ดถัดไป มันเป็นแบบซิงโครนัส แต่บางครั้งอาจเป็นอันตรายได้ ตัวอย่างเช่นหากฟังก์ชั่นใช้เวลาสักครู่ในการดำเนินการหรือต้องรอบางสิ่งบางอย่างมันจะหยุดทุกสิ่งในระหว่างนั้น
เท่าที่ฉันได้ยิน Google Chrome จะมีจาวาสคริปต์แบบมัลติเธรดดังนั้นจึงเป็นปัญหา "การใช้งานปัจจุบัน"
หากไม่มีการสนับสนุนภาษาที่เหมาะสมสำหรับการทำข้อมูลให้ตรงกันของเธรดจะไม่ทำให้การใช้งานใหม่ลองดู แอป JS ที่ซับซ้อนที่มีอยู่ (เช่นสิ่งใดก็ตามที่ใช้ ExtJS) อาจเกิดปัญหาได้โดยไม่คาดคิด แต่หากไม่มีsynchronized
คำหลักหรือสิ่งที่คล้ายกันก็จะยากมากหรือเป็นไปไม่ได้ที่จะเขียนโปรแกรมใหม่ที่ทำงานอย่างถูกต้อง
อย่างไรก็ตามคุณสามารถใช้ฟังก์ชั่น eval เพื่อให้เกิดภาวะพร้อมกันในบางพื้นที่
/* content of the threads to be run */
var threads = [
[
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');",
"document.write('Foo <br/>');"
],
[
"document.write('Bar <br/>');",
"document.write('Bar <br/>');",
"document.write('Bar <br/>');",
"document.write('Bar <br/>');",
"document.write('Bar <br/>');",
"document.write('Bar <br/>');",
"document.write('Bar <br/>');",
"document.write('Bar <br/>');",
"document.write('Bar <br/>');"
]
];
window.onload = function() {
var lines = 0, quantum = 3, max = 0;
/* get the longer thread length */
for(var i=0; i<threads.length; i++) {
if(max < threads[i].length) {
max = threads[i].length;
}
}
/* execute them */
while(lines < max) {
for(var i=0; i<threads.length; i++) {
for(var j = lines; j < threads[i].length && j < (lines + quantum); j++) {
eval(threads[i][j]);
}
}
lines += quantum;
}
}
Multi-Threading ด้วย javascript นั้นชัดเจนโดยใช้ webworkers ที่นำโดย HTML5
ความแตกต่างที่สำคัญระหว่างผู้ทำงานกับเว็บและสภาพแวดล้อมมัลติเธรดมาตรฐานคือทรัพยากรหน่วยความจำจะไม่แชร์กับเธรดหลักการอ้างอิงไปยังวัตถุไม่สามารถมองเห็นได้จากเธรดหนึ่งไปยังเธรดอื่น เธรดสื่อสารด้วยการแลกเปลี่ยนข้อความดังนั้นจึงเป็นไปได้ที่จะใช้วิธีการซิงโครไนซ์และวิธีการเรียกเมธอดพร้อมกันตามรูปแบบการออกแบบที่ขับเคลื่อนด้วยเหตุการณ์
มีเฟรมเวิร์กจำนวนมากที่อนุญาตให้สร้างโครงสร้างการเขียนโปรแกรมระหว่างเธรดซึ่งในหมู่พวกเขา OODK-JS เป็นเฟรมเวิร์ก OOP js ที่สนับสนุนการเขียนโปรแกรมพร้อมกัน https://github.com/GOMServices/oodk-js-oop-for-js