2012-07-06 14 views
25

Biz böyle HTML5 web işçisi kullanabilirsiniz:Neden Ağ Yapıcı doğrudan bir işlev arayamam?

var worker = new Worker('worker.js'); 

ama neden böyle bir işlevi demiyorlar?

var worker = new Worker(function(){ 
    //do something 
}); 
+2

Size yardımcı olabilecek başka bir eklenti [vkThread] (http://www.eslinstructor.net/vkthread/). [Http://www.eslinstructor.net/vkthread/](http://www.eslinstructor.net/vkthread/] adresine bir bakın. Orada örnekler ve belgeler bulacaksınız. – vadimk

+0

Bir URL kullanmanız gerekiyor, ancak bazı tarayıcılar bir BLOB URL'si kullanmanıza izin verecek. Bir örnek için [this] (http://stackoverflow.com/a/6454685/19676) yanıtına bakın. – Maurice

+0

@Qix, başka bir yanıtta yorumda bulunduğundan, vkThread ayrıca tarayıcılar arasında tutarsızlık getiren function.toString öğesine dayandırılmıştır. –

cevap

17

Bu, web çalışanlarının tasarlanma şeklidir. Kendi harici JS dosyalarına ve bu dosya tarafından başlatılan kendi ortamlarına sahip olmalıdırlar. Çok iş parçacıklı çatışmayla ilgili nedenlerle, düzenli bir ortamdaki JS alanınızla bir ortamı paylaşamazlar. web işçileri global değişkenlere doğrudan erişim izin verilmediğini

bir nedeni de (ve ciddiye karmaşık hale getireceği) kullanılabilir bir şey değildir iki ortam arasında iplik senkronizasyonu gerektirecektir olmasıdır. web işçileri kendi ayrı global değişkenler var, onlar düzgün ana JS iplikle senkronize edilir mesajlaşma kuyruğunda yoluyla hariç ana JS iplikle değil dalaşamaz.

Belki bir gün, daha gelişmiş JS programcıları ortak değişkenlere erişimi paylaşmak için geleneksel iş parçacığı senkronizasyon tekniklerini kullanabilir, ancak şimdilik iki iş parçacığı arasındaki tüm iletiler ileti sırasından geçmeli ve web çalışanı erişime sahip olamaz. ana Javascript iş parçacığı ortamı.

+0

kabul etti, biraz zamanımız var ama yolumuza geldik. –

+0

Ben javascript Tek iş parçacıklı olduğunu düşünüyorum.Ama kroswer Çok iş parçacıklı sayfaları açabilir ve çalıştırabilirsiniz. Bu yüzden, web çalışanı yeni bir sayfa oluşturuyor (ya da yeni bir ortam mı diyor) ve betiği çalıştırabiliyor? Yani web çalışanı sadece harici bir JS dosyasını arayabilir. – Dozer

+0

@Dozer - bu temel olarak doğru. Ana javascript iş parçacığı tek iş parçacıklı ve web üzerinde çok javascript kodu olduğunu varsayar. Genel çoklu yayınlamaya izin vermek için gelişmiş iş parçacığı senkronizasyon araçlarını eklemek yerine, web çalışanlarını tasarlayanlar daha küçük bir adım atmaya ve yeni bir ileti dizisine izin vermeye karar verdiler, ancak SADECE yeni bir JS dosyası aracılığıyla kendi küresel ortamını başlatıyorsa ve herhangi bir global erişimi Mesaj kuyruğu ile senkronize edildiğinde ana iş parçacığı. Bu, thread'ler arasındaki global değişken senkronizasyon sorunlarını önler. – jfriend00

8

Bu soru before istendi, ama nedense, OP silmeye karar:

bakın.
Ben durumda bir bir işlevden bir Web işçiyi oluşturmak için bir yöntem gereklidir, benim cevap Repost.


this post yılında üç yolu keyfi bir dizesinden bir Web işçiyi oluşturmak gösterilmiştir. Bu yanıtta, tüm ortamlarda desteklendiği için üçüncü yöntemi kullanıyorum. kapsamları kesinlikle ayrılır

// Create a Web Worker from a function, which fully runs in the scope of a new 
// Worker 
function spawnWorker(func) { 
    // Stringify the code. Example: (function(){/*logic*/}).call(self); 
    var code = '(' + func + ').call(self);'; 
    var worker = new Worker('Worker-helper.js'); 
    // Initialise worker 
    worker.postMessage(code); 
    return worker; 
} 

var worker = spawnWorker(function() { 
    // This function runs in the context of a separate Worker 
    self.onmessage = function(e) { 
     // Example: Throw any messages back 
     self.postMessage(e.data); 
    }; 
    // etc.. 
}); 
worker.onmessage = function() { 
    // logic ... 
}; 
worker.postMessage('Example'); 

Not olun:

bir yardımcı dosyasını gereklidir: aşağıdaki gibi gerçek asistant

// Worker-helper.js 
self.onmessage = function(e) { 
    self.onmessage = null; // Clean-up 
    eval(e.data); 
}; 

, bu yardımcı dosyası kullanılır. Değişkenler sadece worker.postMessage ve worker.onmessage kullanarak ileri geçti ve edilebilir. Tüm mesajlar structured clones.

+0

Bu, "Function.toString()" ifadesinin, belirli ortamlarda OLMAYAN bir un-eval decompiler olarak çalıştığını varsayar. Dikkatle kullanın! – Qix

+0

@Qix Web Çalışanlarının desteklendiği en az bir ortak tarayıcıyı adlandırabiliyorsanız, ancak kullanıcı tanımlı bir işlevdeki 'toString()' adının varsayılan olarak işlevsel olarak eşdeğer bir kaynak döndürmemesi durumunda, daha yararlı olacaktır. –

+0

Tarayıcılar, yalnızca Javascript ortamları değildir. Mesele şu ki, bu W3C standardının yanı sıra Ecmascript standartlarına da (fonksiyonların decompiled edilmemesi gerekiyordu; bunu destekleyen ortamlar, sadece hata ayıklama amaçları için ek bir özellik olarak sunuluyor). – Qix

3

Bu cevap biraz geç olabilir ama ben web işçilerin kullanımını kolaylaştırmak için bir kütüphane yazdım ve OP'ın ihtiyaçlarına uygun olabilir.Bu böyle bir şey yapmak için izin verir https://github.com/derekchiang/simple-worker

: Check it out Sadece https://github.com/zevero/worker-create

benim minik eklenti kullanmak

SimpleWorker.run({ 
    func: intensiveFunction, 
    args: [123456], 
    success: function(res) { 
    // do whatever you want 
    }, 
    error: function(err) { 
    // do whatever you want 
    } 
}) 
+0

Bu, @ vadimk'in vkThread mesajına oldukça benzer görünüyor - açıkçası farklı projeler, ancak vkThread'in iyi çalıştığını söyleyebilirim ve kullanım için birkaç farklı yöntemi vardır. – Nick

0

ve optimum olmasa da

var worker_url = Worker.create(function(e){ 
    self.postMessage('Example post from Worker'); //your code here 
}); 
var worker = new Worker(worker_url); 
1

yapmak ve zaman oldu yorumlarda belirtildiği gibi, tarayıcınız Web Çalışanlar için blobURL'leri destekliyorsa harici dosyaya gerek yoktur. HTML5Rocks benim kodu için inspiration oldu:

function sample(e) 
{ 
    postMessage(sample_dependency()); 
} 

function sample_dependency() 
{ 
    return "BlobURLs rock!"; 
} 

var blob = new Blob(["onmessage = " + sample + "\n" + sample_dependency]); 
var blobURL = window.URL.createObjectURL(blob); 
var worker = new Worker(blobURL); 

worker.onmessage = function(e) 
{ 
    console.log(e.data); 
}; 

worker.postMessage(""); 

Uyarılar:

  • damla işçileri başarıyla göreli URL'ler kullanmaz. HTML5Rocks bağlantısı bunu kapsar, ancak asıl sorunun bir parçası değildi.

  • Kişiler, Web Çalışanı olan Blob URL'lerini kullanarak sorunları bildirdiler. IE11 (FCU ile birlikte gönderilenler), MS Edge 41.16299 (Güz Creator Güncellemesi), Firefox 57 ve Chrome 62 ile denedim. Safari desteği konusunda hiçbir ipucu yok. Test ettiğim kişiler işe yaradı.

  • Blob yapıcı çağrısında "örnek" ve "sample_dependency" referanslar örtülü toString(sample) ve toString(sample_dependency) arayarak çok farklı olan sample.toString() ve sample_dependency.toString() olarak Function.prototype.toString() dediğimiz Not. ek bir dosya talep etmeden Web Workers nasıl kullanılacağı ararken gelen ilk stackoverflow çünkü

bu Yayınlanan.

Zevero'nun cevabına bir bakış ve onun repolarındaki kod benzer görünüyor. Temiz bir sarıcı tercih ederseniz, bu onun kodunun yaptığı şeydir.

Son olarak - burada bir noob var, böylece her türlü düzeltme takdir ediliyor.

İlgili konular