Kasıtlı bir tasarım kararı mı yoksa gelecek sürümlerde düzeltilecek mevcut tarayıcılarımızla ilgili bir sorun mu?
Kasıtlı bir tasarım kararı mı yoksa gelecek sürümlerde düzeltilecek mevcut tarayıcılarımızla ilgili bir sorun mu?
Yanıtlar:
Tarayıcıdaki JavaScript yorumlayıcısı tek bir iş parçacığı (AFAIK) olduğu için JavaScript çoklu iş parçacığını desteklemiyor. Google Chrome bile tek bir web sayfasının JavaScript'inin aynı anda çalışmasına izin vermez, çünkü bu mevcut web sayfalarında büyük eşzamanlılık sorunlarına neden olur. Tüm Chrome'un yaptığı ayrı işlemler, birden çok bileşeni (farklı sekmeler, eklentiler, vb.) Ayrı işlemlere ayırmaktır, ancak birden fazla JavaScript iş parçacığına sahip tek bir sayfa düşünemiyorum.
Bununla birlikte, önerildiği gibi, setTimeout
bir tür programlama ve “sahte” eşzamanlılığa izin vermek için kullanabilirsiniz . Bu, tarayıcının oluşturma iş parçacığının denetimini yeniden ele geçirmesine setTimeout
ve verilen milisaniyeden sonra verilen JavaScript kodunu başlatmasına neden olur . Bu, üzerinde işlem yaparken görünümün (gördüklerinizin) yenilenmesine izin vermek istiyorsanız çok kullanışlıdır. Sadece koordinatlar arasında geçiş yapmak ve bir elemanı buna göre güncellemek sadece başlangıç ve bitiş konumlarını görmenizi sağlar ve aradaki hiçbir şeyi görmez.
JavaScript'te, hepsi aynı JavaScript yorumlayıcısı tarafından yönetilen işlemler ve iş parçacıkları oluşturmamızı sağlayan bir soyutlama kitaplığı kullanıyoruz. Bu, eylemleri aşağıdaki şekilde yürütmemizi sağlar:
Bu, bir tür zamanlamaya ve paralelliğe, ipliklerin başlatılmasına ve durdurulmasına vb. İzin verir, ancak gerçek çoklu iş parçacığı olmayacaktır. Gerçek dil iş parçacığının yalnızca tarayıcı tek iş parçacıklı çok iş parçacıklı (veya birden fazla çekirdeği) çalıştırabildiği ve çok daha büyük zorlukları olduğu için dilin kendisinde uygulanacağını düşünmüyorum ekstra olasılıklardan daha fazla.
JavaScript'in geleceği için şu adrese göz atın: https://developer.mozilla.org/presentations/xtech2006/javascript/
JavaScript çoklu iş parçacığı (bazı sınırlamalarla) burada. Google, Gears için çalışanları uyguladı ve çalışanlar HTML5'e dahil edildi. Çoğu tarayıcı bu özellik için zaten destek ekledi.
İşçiye / çalışandan iletilen tüm veriler serileştirildiği / kopyalandığı için verilerin iş parçacığı güvenliği garanti edilir.
Daha fazla bilgi için okuyun:
Geleneksel olarak, JS kısa, hızlı çalışan kod parçaları için tasarlanmıştır. Büyük hesaplamalar yapıyorsanız, bunu bir sunucuda yaptınız - tarayıcınızda uzun süre çalışan bir JS + HTML uygulaması fikri önemsiz şeyler yapmak saçma oldu.
Tabii ki, şimdi buna sahibiz. Ancak, tarayıcıların yakalaması biraz zaman alacak - çoğu tek iş parçacıklı bir model etrafında tasarlandı ve değiştirmek kolay değil. Google Gears, arka planda yürütmenin izole edilmesini gerektirerek birçok potansiyel sorunu yan adımlara yönlendirir - DOM'yi değiştirmez (iş parçacığı için güvenli olmadığı için), ana iş parçacığı (ditto) tarafından oluşturulan erişilen nesneler yoktur. Kısıtlayıcı olmakla birlikte, bu, hem tarayıcının tasarımını basitleştirdiği hem de deneyimsiz JS kodlayıcılarının iş parçacıkları ile uğraşmasına izin verme riskini azalttığı için yakın gelecekte en pratik tasarım olacaktır ...
@marcio :
Neden Javascript'te çoklu iş parçacığı uygulamak için bir neden? Programcılar sahip oldukları araçlar ile istediklerini yapabilirler.
Öyleyse, onlara açtığım diğer tüm web sitelerinin tarayıcımı çökmesine neden olacak şekilde kötüye kullanımı kolay araçlar vermeyelim . Bunun naif bir uygulaması sizi doğrudan IE7 gelişimi sırasında MS'e çok fazla baş ağrısına neden olan bölgeye getirecektir: eklenti yazarları, iplik geçirme modeliyle hızlı ve gevşek oynadılar, bu da birincil iplik üzerinde nesne yaşam döngüleri değiştiğinde ortaya çıkan gizli hatalarla sonuçlandı . KÖTÜ. IE için çok iş parçacıklı ActiveX eklentileri yazıyorsanız, sanırım bölge ile birlikte gelir; bundan daha ileri gitmesi gerektiği anlamına gelmez.
Bu kararın mantığını bilmiyorum, ancak setTimeout kullanarak çok iş parçacıklı programlamanın bazı avantajlarını simüle edebileceğinizi biliyorum. Gerçekte her şey tek bir iş parçacığında gerçekleşse de, aynı anda bir şeyler yaparak birden çok işlem yanılsamasını verebilirsiniz.
Sadece işlevinizin biraz iş yapmasını sağlayın ve sonra şöyle bir şey çağırın:
setTimeout(function () {
... do the rest of the work...
}, 0);
Ve yapılması gereken diğer şeyler (UI güncellemeleri, animasyonlu resimler vb.) Bir şans elde ettiklerinde gerçekleşir.
loop
iç kullanmak istiyorum , setTimeout
ama görünüşe göre bu işe yaramaz. Böyle bir şey yaptın mı yoksa bir hackin var mı? bir örnek 1000 eleman dizisi için olurdu, ben setTimeout
ilk aramalar üzerinden ve baskı elemanı 0..499
, ikinci döngüler üzerinden ve baskı elemanı olacak şekilde iki çağrı içinde döngüler için iki kullanmayı umuyoruz 500..999
.
Yani dil neden çoklu okumayı desteklemiyor veya tarayıcılardaki JavaScript motorları neden çoklu okumayı desteklemiyor?
İlk sorunun cevabı, tarayıcıdaki JavaScript'in bir sanal alanda ve makineden / işletim sisteminden bağımsız bir şekilde çalıştırılması, çoklu iş parçacığı desteği eklemenin dili karmaşıklaştıracağı ve dili işletim sistemine çok yakın bağlayacağıdır.
Node.js 10.5+, çalışan iş parçacıklarını deneysel özellik olarak destekler ( --exorimental-worker bayrağı etkinken kullanabilirsiniz): https://nodejs.org/api/worker_threads.html
Yani, kural:
Çalışan iş parçacıklarının uzun ömürlü iş parçacıkları olması amaçlanmıştır, yani bir arka plan iş parçacığı oluşturursunuz ve daha sonra onunla mesaj ileterek iletişim kurarsınız.
Aksi takdirde, anonim bir işlevle ağır bir CPU yükü yürütmeniz gerekiyorsa , çalışan iş parçacıklarının etrafında inşa edilmiş küçük bir kütüphane olan https://github.com/wilk/microjob ile gidebilirsiniz .
Matt b'nin dediği gibi, soru çok açık değil. Dilde çoklu iş parçacığı desteği istediğini varsayarsak: şu anda tarayıcıda çalışan uygulamaların% 99,999'u için gerekli olmadığından. Gerçekten ihtiyacınız varsa, geçici çözümler vardır (window.setTimeout kullanmak gibi).
Genel olarak çoklu iş parçacığı, ekstra kısıtlamalar koymadığınız sürece (sadece değişmez veriler kullanmak gibi) doğru olmak için çok, çok, çok, çok, çok, çok zor (zor olduğunu mu söyledim?).
Intel, Javascript'te çok iş parçacığına ilişkin bazı açık kaynaklı araştırmalar yapıyor, son zamanlarda GDC 2012'de sergilendi. İşte video için link . Araştırma grubunda öncelikle Intel Chip setleri ve Windows işletim sistemine odaklanan OpenCL kullanılmıştır. Proje kod adı RiverTrail'dir ve kod GitHub'da kullanılabilir
Bazı yararlı bağlantılar:
Şu anda bazı tarayıcılar çoklu iş parçacığı kullanımını desteklemektedir. Yani, ihtiyacınız varsa belirli kütüphaneleri kullanabilirsiniz. Örneğin, aşağıdaki malzemeleri görüntüleyin:
https://developer.mozilla.org/tr-TR/docs/Web/API/Web_Workers_API/Using_web_workers (arka plan iş parçacıklarını destekleyin);
https://keithwhor.github.io/multithread.js/ (kütüphane).
Çoklu diş açmayı desteklemeyen uygulamalar. Şu anda Google Gears, harici işlemleri yürüterek bir tür eşzamanlılık kullanmanın bir yolunu sunuyor, ancak hepsi bu.
Google'ın bugün yayınlaması beklenen yeni tarayıcı (Google Chrome), devam etmekte olan bazı kodları paralel olarak yürütmektedir.
Temel dil, elbette, Java ile aynı desteğe sahip olabilir, ancak Erlang'ın eşzamanlılığı gibi bir şey için destek ufukta hiçbir yerde değildir.
Javascript tek iş parçacıklı bir dildir. Bu, bir çağrı yığını ve bir bellek yığını olduğu anlamına gelir. Beklendiği gibi, kodu sırayla yürütür ve bir sonrakine geçmeden önce bir parça kodunu yürütmeyi bitirmelidir. Eşzamanlı, ancak zaman zaman zararlı olabilir. Örneğin, bir işlevin yürütülmesi biraz zaman alırsa veya bir şeyi beklemek zorunda kalırsa, bu arada her şeyi dondurur.
İş parçacığı senkronizasyonu için uygun dil desteği olmadan, yeni uygulamaların denenmesi bile mantıklı değildir. Mevcut karmaşık JS uygulamaları (örneğin, ExtJS kullanan herhangi bir şey) büyük olasılıkla beklenmedik bir şekilde kilitlenir, ancak bir synchronized
anahtar kelime veya benzer bir şey olmadan , doğru davranan yeni programlar yazmak da çok zor hatta imkansız olabilir.
Ancak, bazı işlevleri eşzamanlılık getirmek için eval işlevini kullanabilirsiniz.
/* 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;
}
}
Javascript ile çoklu iş parçacıkları HTML5 tarafından getirilen web işçileri kullanılarak açıkça mümkündür.
Web çalışanları ve standart çok iş parçacıklı ortam arasındaki temel fark, bellek kaynaklarının ana iş parçacığı ile paylaşılmamasıdır, bir nesneye yapılan başvuru bir iş parçacığından diğerine görünmez. İş parçacıkları mesaj alışverişi yoluyla iletişim kurarlar, bu nedenle olaya dayalı bir tasarım modelinin ardından bir senkronizasyon ve eşzamanlı yöntem çağrı algoritması uygulamak mümkündür.
İş parçacıkları arasında programlamanın yapılandırılmasına izin veren birçok çerçeve vardır, aralarında aynı anda programlamayı destekleyen bir OOP js çerçevesi olan OODK-JS, https://github.com/GOMServices/oodk-js-oop-for-js