Đây có phải là một quyết định thiết kế có chủ ý hay là một vấn đề với các trình duyệt hiện tại của chúng tôi sẽ được khắc phục trong các phiên bản sắp tới?
Đây có phải là một quyết định thiết kế có chủ ý hay là một vấn đề với các trình duyệt hiện tại của chúng tôi sẽ được khắc phục trong các phiên bản sắp tới?
Câu trả lời:
JavaScript không hỗ trợ đa luồng vì trình thông dịch JavaScript trong trình duyệt là một luồng đơn (AFAIK). Ngay cả Google Chrome cũng sẽ không để JavaScript của một trang web chạy đồng thời vì điều này sẽ gây ra sự cố đồng thời lớn trong các trang web hiện tại. Tất cả Chrome thực hiện là tách nhiều thành phần (các tab, trình cắm, v.v.) khác nhau thành các quy trình riêng biệt, nhưng tôi không thể tưởng tượng một trang duy nhất có nhiều hơn một luồng JavaScript.
Tuy nhiên, bạn có thể sử dụng, như đã được đề xuất, setTimeout
để cho phép một số loại lập kế hoạch và đồng thời giả mạo. Điều này khiến trình duyệt lấy lại quyền kiểm soát luồng kết xuất và bắt đầu mã JavaScript được cung cấp setTimeout
sau số mili giây đã cho. Điều này rất hữu ích nếu bạn muốn cho phép chế độ xem (những gì bạn thấy) làm mới trong khi thực hiện các thao tác trên nó. Chỉ cần lặp qua các tọa độ ví dụ và cập nhật một phần tử tương ứng sẽ cho phép bạn thấy các vị trí bắt đầu và kết thúc, và không có gì ở giữa.
Chúng tôi sử dụng một thư viện trừu tượng trong JavaScript cho phép chúng tôi tạo các quy trình và luồng được quản lý bởi cùng một trình thông dịch JavaScript. Điều này cho phép chúng tôi chạy các hành động theo cách sau:
Điều này cho phép một số hình thức lập lịch và thực hiện song song, bắt đầu và dừng các luồng, vân vân, nhưng nó sẽ không phải là đa luồng thực sự. Tôi không nghĩ nó sẽ được thực hiện bằng chính ngôn ngữ này, vì đa luồng thực sự chỉ hữu ích nếu trình duyệt có thể chạy một trang đa luồng (hoặc thậm chí nhiều hơn một lõi) và những khó khăn còn lớn hơn hơn các khả năng bổ sung.
Để biết tương lai của JavaScript, hãy xem điều này: https://developer.mozilla.org/presentations/xtech2006/javascript/
JavaScript đa luồng (với một số hạn chế) có ở đây. Google đã triển khai các công nhân cho Gears và các công nhân đang được đưa vào HTML5. Hầu hết các trình duyệt đã thêm hỗ trợ cho tính năng này.
An toàn luồng dữ liệu được đảm bảo vì tất cả dữ liệu được truyền đến / từ công nhân được tuần tự hóa / sao chép.
Để biết thêm thông tin, đọc:
Theo truyền thống, JS được dành cho các đoạn mã ngắn, chạy nhanh. Nếu bạn có những tính toán lớn đang diễn ra, bạn đã thực hiện nó trên một máy chủ - ý tưởng về một ứng dụng JS + HTML chạy trong trình duyệt của bạn trong thời gian dài làm những việc không tầm thường là vô lý.
Tất nhiên, bây giờ chúng tôi có điều đó. Tuy nhiên, sẽ cần một chút để các trình duyệt bắt kịp - hầu hết chúng được thiết kế xung quanh một mô hình đơn luồng và việc thay đổi điều đó không dễ dàng. Google Gears xử lý rất nhiều vấn đề tiềm ẩn bằng cách yêu cầu thực thi nền được cách ly - không thay đổi DOM (vì điều đó không an toàn cho luồng), không truy cập các đối tượng được tạo bởi luồng chính (ditto). Mặc dù hạn chế, đây có thể sẽ là thiết kế thiết thực nhất cho tương lai gần, bởi vì nó đơn giản hóa thiết kế của trình duyệt và vì nó giảm rủi ro liên quan đến việc cho phép các lập trình viên JS thiếu kinh nghiệm làm rối tung các luồng ...
@marcio :
Tại sao đó là một lý do để không triển khai đa luồng trong Javascript? Các lập trình viên có thể làm bất cứ điều gì họ muốn với các công cụ họ có.
Vì vậy, sau đó, đừng cung cấp cho họ các công cụ dễ sử dụng đến mức mọi trang web khác tôi mở đều bị sập trình duyệt của tôi. Việc triển khai ngây thơ này sẽ đưa bạn vào thẳng lãnh thổ khiến MS rất đau đầu trong quá trình phát triển IE7: các tác giả bổ trợ đã chơi nhanh và lỏng lẻo với mô hình luồng, dẫn đến các lỗi ẩn rõ ràng khi vòng đời đối tượng thay đổi trên luồng chính . XẤU. Nếu bạn đang viết các tiện ích ActiveX đa luồng cho IE, tôi đoán nó đi kèm với lãnh thổ; không có nghĩa là nó cần phải đi xa hơn thế.
Tôi không biết lý do căn bản cho quyết định này, nhưng tôi biết rằng bạn có thể mô phỏng một số lợi ích của lập trình đa luồng bằng cách sử dụng setTimeout. Bạn có thể ảo tưởng về nhiều quá trình thực hiện cùng một lúc, mặc dù trong thực tế, mọi thứ xảy ra trong một luồng.
Chỉ cần có chức năng của bạn làm một chút công việc, và sau đó gọi một cái gì đó như:
setTimeout(function () {
... do the rest of the work...
}, 0);
Và bất kỳ điều gì khác cần làm (như cập nhật giao diện người dùng, hình ảnh hoạt hình, v.v.) sẽ xảy ra khi họ có cơ hội.
loop
bên trong setTimeout
nhưng dường như không hoạt động. Bạn đã làm bất cứ điều gì như vậy hoặc bạn có một hack? một ví dụ sẽ là mảng 1000 phần tử, tôi dự kiến sẽ sử dụng hai cho các vòng lặp bên trong hai setTimeout
lệnh gọi sao cho các vòng lặp đầu tiên và phần tử in 0..499
, các vòng lặp thứ hai xuyên qua và phần tử in 500..999
.
Ý bạn là tại sao ngôn ngữ không hỗ trợ đa luồng hay tại sao các công cụ JavaScript trong trình duyệt không hỗ trợ đa luồng?
Câu trả lời cho câu hỏi đầu tiên là JavaScript trong trình duyệt có nghĩa là được chạy trong hộp cát và theo cách độc lập với máy / HĐH, để thêm hỗ trợ đa luồng sẽ làm phức tạp ngôn ngữ và gắn ngôn ngữ quá chặt chẽ với HĐH.
Node.js 10.5+ hỗ trợ các luồng công nhân làm tính năng thử nghiệm (bạn có thể sử dụng nó với cờ --experimental-worker được bật): https://nodejs.org/api/worker_threads.html
Vì vậy, quy tắc là:
Chủ đề công nhân được dự định là chủ đề sống lâu, có nghĩa là bạn sinh ra một chủ đề nền và sau đó bạn giao tiếp với nó thông qua tin nhắn đi qua.
Mặt khác, nếu bạn cần thực thi tải CPU nặng với chức năng ẩn danh, thì bạn có thể truy cập https://github.com/wilk/microjob , một thư viện nhỏ được xây dựng xung quanh các luồng công nhân.
Như matt b đã nói, câu hỏi không rõ ràng lắm. Giả sử rằng bạn đang hỏi về hỗ trợ đa luồng trong ngôn ngữ: bởi vì hiện tại không cần thiết cho 99.999% ứng dụng đang chạy trong trình duyệt. Nếu bạn thực sự cần nó, có cách giải quyết (như sử dụng window.setTimeout).
Nói chung, đa luồng là rất, rất, rất, rất, rất, rất khó (tôi có nói là khó không?) Để có được quyền, trừ khi bạn đặt thêm các hạn chế (như chỉ sử dụng dữ liệu bất biến).
Intel đã thực hiện một số nghiên cứu mã nguồn mở về đa luồng trong Javascript, nó đã được giới thiệu gần đây trên GDC 2012. Đây là liên kết cho video . Nhóm nghiên cứu đã sử dụng OpenCL, chủ yếu tập trung vào các bộ Intel Chip và HĐH Windows. Dự án có tên mã là RiverTrail và mã này có sẵn trên GitHub
Một số liên kết hữu ích hơn:
Hiện tại một số trình duyệt hỗ trợ đa luồng. Vì vậy, nếu bạn cần rằng bạn có thể sử dụng các thư viện cụ thể. Ví dụ: xem các tài liệu tiếp theo:
https://developer.mozilla.org/en-US/docs/Web/API/Web_WorkftimeAPI/Using_web_workers (hỗ trợ chủ đề nền);
https://keithwhor.github.io/multithread.js/ (thư viện).
Đó là các triển khai không hỗ trợ đa luồng. Hiện tại Google Gears đang cung cấp một cách để sử dụng một số hình thức đồng thời bằng cách thực hiện các quy trình bên ngoài nhưng đó là về nó.
Trình duyệt mới mà Google dự kiến sẽ phát hành hôm nay (Google Chrome) thực thi một số mã song song bằng cách tách nó trong quá trình.
Tất nhiên, ngôn ngữ cốt lõi có thể có cùng sự hỗ trợ như Java, nhưng hỗ trợ cho một thứ như đồng thời của Erlang không ở đâu gần đường chân trời.
Javascript là một ngôn ngữ đơn luồng. Điều này có nghĩa là nó có một ngăn xếp cuộc gọi và một đống bộ nhớ. Như mong đợi, nó thực thi mã theo thứ tự và phải hoàn thành việc thực thi mã mảnh trước khi chuyển sang mã tiếp theo. Nó đồng bộ, nhưng đôi khi có thể gây hại. Ví dụ, nếu một hàm mất một thời gian để thực thi hoặc phải chờ một cái gì đó, thì nó sẽ đóng băng mọi thứ trong khi đó.
Nếu không có sự hỗ trợ ngôn ngữ phù hợp cho quá trình đồng bộ hóa luồng, thậm chí sẽ không có ý nghĩa đối với việc triển khai mới để thử. Các ứng dụng JS phức tạp hiện có (ví dụ: mọi thứ sử dụng ExtJS) rất có thể bị sập bất ngờ, nhưng không có synchronized
từ khóa hoặc thứ gì đó tương tự, sẽ rất khó hoặc thậm chí không thể viết các chương trình mới hoạt động chính xác.
Tuy nhiên, bạn có thể sử dụng chức năng eval để mang lại sự đồng thời cho MỘT SỐ TUYỆT VỜI
/* 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;
}
}
Đa luồng với javascript rõ ràng là có thể sử dụng webworkers do HTML5 mang lại.
Sự khác biệt chính giữa webworkers và môi trường đa luồng tiêu chuẩn là tài nguyên bộ nhớ không được chia sẻ với luồng chính, tham chiếu đến một đối tượng không thể nhìn thấy từ luồng này sang luồng khác. Chủ đề giao tiếp bằng cách trao đổi thông điệp, do đó có thể thực hiện thuật toán gọi phương thức đồng bộ hóa và đồng thời theo mẫu thiết kế hướng sự kiện.
Nhiều khung tồn tại cho phép cấu trúc chương trình giữa các luồng, trong số đó có 3MK-JS, khung OOP js hỗ trợ lập trình đồng thời https://github.com/GOMService/oodk-js-oop-for-js