ওয়েব কর্মীরা আলাদা জাভাস্ক্রিপ্ট ফাইল ছাড়াই?


291

আমি যতদূর বলতে পারি, ওয়েব কর্মীদের একটি আলাদা জাভাস্ক্রিপ্ট ফাইলে লিখতে হবে, এবং এ জাতীয় বলা হবে:

new Worker('longrunning.js')

আমি আমার সমস্ত জাভাস্ক্রিপ্ট উত্স কোড একত্রিত করতে এবং এটি নিখুঁত করতে ক্লোজার সংকলকটি ব্যবহার করছি, এবং বিতরণ করার জন্য আমার কর্মীদের আলাদা ফাইলে রাখতে হবে না। এই কাজ করতে কিছু উপায় আছে কি?

new Worker(function() {
    //Long-running work here
});

প্রথম শ্রেণীর ফাংশনগুলি জাভাস্ক্রিপ্টের জন্য এতটা গুরুত্বপূর্ণ যে দেওয়া হয়েছে, পশ্চাদপটের কাজটি করার স্ট্যান্ডার্ড পদ্ধতিতে কেন ওয়েব সার্ভার থেকে পুরো অন্যান্য জাভাস্ক্রিপ্ট ফাইলটি লোড করতে হবে?


7
এটি কারণ যে মৃত্যুদন্ড কার্যকর করার প্রসঙ্গটি বিশুদ্ধভাবে থ্রেডসেফ রাখা প্রথম-শ্রেণীর ফাংশনগুলির চেয়েও বেশি গুরুত্বপূর্ণ :-)
পয়েন্টি

1
আমি এটিতে কাজ করছি (বা বরং সমস্যা হ্রাস করার জন্য): ডাইন ওয়ার্কার । আপনি এটি করতে পারেন: var worker = new DynWorker(); worker.inject("foo", function(){...});...
ফলিক্স সাপারেলি


1
ওপি "জাভাস্ক্রিপ্ট উত্স ফাইলের পরিবর্তে ফাংশন গ্রহণ করতে শিক্ষকতা কর্মী" মুছে ফেলেছে। উত্তরটি এখানে পুনরায় পোস্ট করা হয়েছে
রব ডাব্লু

এটি করা আরও সহজ করার জন্য আমি টাস্ক.জেএস তৈরি করেছি । বেশিরভাগ সময় আপনি কেবলমাত্র ছোট লকিংয়ের কাজগুলি অফলোড করার চেষ্টা করছেন।
চাদ সায়রা

উত্তর:


225

http://www.html5rocks.com/en/tutorials/workers/basics/#toc-inlineworkers

আপনি যদি উড়তে আপনার কর্মী স্ক্রিপ্ট তৈরি করতে চান বা আলাদা কর্মী ফাইল তৈরি না করে একটি স্বয়ংসম্পূর্ণ পৃষ্ঠা তৈরি করতে চান তবে কী হবে? ব্লব () এর সাহায্যে আপনি কর্মী কোডটিতে স্ট্রিং হিসাবে একটি ইউআরএল হ্যান্ডেল তৈরি করে আপনার মূল যুক্তির মতো একই HTML ফাইলটিতে আপনার কর্মীকে "ইনলাইন" করতে পারেন


বিএলওবি ইনলাইন কর্মীর পুরো উদাহরণ:

<!DOCTYPE html>
<script id="worker1" type="javascript/worker">
  // This script won't be parsed by JS engines because its type is javascript/worker.
  self.onmessage = function(e) {
    self.postMessage('msg from worker');
  };
  // Rest of your worker code goes here.
</script>
<script>
  var blob = new Blob([
    document.querySelector('#worker1').textContent
  ], { type: "text/javascript" })

  // Note: window.webkitURL.createObjectURL() in Chrome 10+.
  var worker = new Worker(window.URL.createObjectURL(blob));
  worker.onmessage = function(e) {
    console.log("Received: " + e.data);
  }
  worker.postMessage("hello"); // Start the worker.
</script>


গুগল ক্রোমের একমাত্র সমাধান, ফায়ারফক্স 10 এটি সমর্থন করবে বলে মনে হয়, আমি অন্যান্য ব্রাউজারগুলির সম্পর্কে জানি না
4esn0k

2
ব্লববিলার এখন অবহেলিত । ব্যবহারের ব্লব পরিবর্তে। বর্তমানে সর্বশেষতম ফায়ারফক্স / ওয়েবকিট / অপেরা এবং আই 10 তে সমর্থিত, পুরানো ব্রাউজারগুলির জন্য সামঞ্জস্যতা সারণী দেখুন ।
ফলিক্স সাপারেলি

3
IE10 এ ব্লব কনস্ট্রাক্টর সমর্থিত হতে পারে তবে আপনি এখনও এটির মাধ্যমে ওয়েব কর্মীর কাছে জাভাস্ক্রিপ্ট পাস করতে পারবেন না (এমনকি আইই 11 তেও নয়): কানেক্ট.মাইক্রোসফট / আইই / ফেডব্যাক / ডেটেল / 801810/…
জয়য়ারজো

1
@ আলবানেক্স-কি পরীক্ষা? ইতিমধ্যে অনলাইনে বিলিয়ন ডেমো পৃষ্ঠাগুলি রয়েছে যা দেখায় যে থ্রেডিং কয়েক বছরের জন্য ব্রাউজারটিকে হ্যাং আপ করে না।
vsync

2
@ আলবানেক্স - আপনি কমপক্ষে কোনটি বলবেন যে কোন ঝুলন্ত ব্রাউজারটি আপনি ব্যবহার করেন? এই ডেমোটি কি আপনার জন্য ঝুলছে? অর্থ্যাৎ.মাইক্রোসফট.টাস্টেড্রাইভ
গ্রাফিক্স /

162

এইচটিএমএলে ওয়েব কর্মী কোড এম্বেড করার html5rocks সমাধান মোটামুটি ভয়াবহ।
এবং পালিয়ে যাওয়া জাভাস্ক্রিপ্ট-এর-এ-স্ট্রিংয়ের একটি ব্লব আরও ভাল নয়, কমপক্ষে নয় কারণ এটি কাজের প্রবাহকে জটিল করে তোলে (বন্ধ সংকলক স্ট্রিংগুলিতে কাজ করতে পারে না)।

ব্যক্তিগতভাবে আমি টসস্ট্রিং পদ্ধতিগুলি পছন্দ করি তবে @ ড্যান-ম্যান TH

আমার পছন্দসই পদ্ধতি:

// Build a worker from an anonymous function body
var blobURL = URL.createObjectURL( new Blob([ '(',

function(){
    //Long-running work here
}.toString(),

')()' ], { type: 'application/javascript' } ) ),

worker = new Worker( blobURL );

// Won't be needing this anymore
URL.revokeObjectURL( blobURL );

সমর্থন হ'ল এই তিনটি সারণীর ছেদ:

এটি অবশ্য ভাগ করা ওয়ার্কারের পক্ষে কাজ করবে না , কারণ mustচ্ছিক 'নাম' প্যারামিটারের সাথে মিল থাকলেও ইউআরএল অবশ্যই একটি সঠিক মিল হতে পারে। শেয়ার্ড ওয়ার্কারের জন্য আপনার আলাদা একটি জাভাস্ক্রিপ্ট ফাইল দরকার।


2015 আপডেট - সার্ভিস ওয়ার্কার এককত্বের আগমন

এখন এই সমস্যাটি সমাধানের আরও শক্তিশালী উপায় রয়েছে। আবার কর্মী কোডটি একটি ফাংশন হিসাবে সংরক্ষণ করুন (স্ট্যাটিক স্ট্রিংয়ের পরিবর্তে) এবং .toString () ব্যবহার করে রূপান্তর করুন, তারপরে কোডটি আপনার পছন্দের স্ট্যাটিক URL এর আওতায় ক্যাশেস্টোরেজে সন্নিবেশ করুন।

// Post code from window to ServiceWorker...
navigator.serviceWorker.controller.postMessage(
 [ '/my_workers/worker1.js', '(' + workerFunction1.toString() + ')()' ]
);

// Insert via ServiceWorker.onmessage. Or directly once window.caches is exposed
caches.open( 'myCache' ).then( function( cache )
{
 cache.put( '/my_workers/worker1.js',
  new Response( workerScript, { headers: {'content-type':'application/javascript'}})
 );
});

দুটি সম্ভাব্য পতন-ব্যাক রয়েছে। উপরের মতো অবজেক্ট ইউআরএল বা আরও নির্বিঘ্নে, একটি বাস্তব রাখুন জাভাস্ক্রিপ্ট ফাইলটি /my_workers/worker1.js এ রাখুন

এই পদ্ধতির সুবিধা হ'ল:

  1. ভাগ করা ওয়ার্কার্সকেও সমর্থন করা যেতে পারে।
  2. ট্যাবগুলি একটি নির্দিষ্ট ঠিকানায় একটি একক ক্যাশেড অনুলিপি ভাগ করতে পারে। ব্লব অ্যাপ্রোচ প্রতিটি ট্যাবটির জন্য এলোমেলোভাবে অবজেক্ট URL গুলিকে প্রসারিত করে।

4
এই সমাধানটিতে ব্রাউজারের সামঞ্জস্যতা কেমন হবে?
বেন দিল্টস

আপনি কি এই সমাধানটি বিশদভাবে বলতে পারেন, এটি কীভাবে কাজ করে? কর্মী 1.js কী? এটি কি আলাদা জেএস ফাইল? আমি এটি ব্যবহার করার চেষ্টা করছি কিন্তু এটি কাজ করতে অক্ষম। বিশেষত আমি এটি একটি ভাগ করা ওয়ার্কারের জন্য কাজ করার চেষ্টা করছি
ইয়েহুদা

যদি আপনি এটি একটি দরকারী ফাংশন মোড়ানো করতে পারে!
মিমি

@ বেন দিল্টস: ব্রাউজারের সামঞ্জস্যতা ঠিক আপনার কোডটি বাবেলের
জ্যাক গিফিন

স্ট্যান্ডার্ডটি গ্যারান্টি দেয় না যে ফাংশন.প্রোটোটাইপ.টোস্ট্রিং () ফাংশনটির মূলটিকে স্ট্রিং হিসাবে ফিরিয়ে দেয়। উত্তরে আপনার সম্ভবত একটি সতর্কতা যুক্ত করা উচিত।
আরডি

37

আপনি একটি একক জাভাস্ক্রিপ্ট ফাইল তৈরি করতে পারেন যা এর প্রয়োগের প্রসঙ্গে সচেতন এবং পিতা বা মাতা স্ক্রিপ্ট এবং কর্মী উভয় হিসাবে কাজ করতে পারে। এর মতো একটি ফাইলের জন্য একটি প্রাথমিক কাঠামো দিয়ে শুরু করা যাক:

(function(global) {
    var is_worker = !this.document;
    var script_path = is_worker ? null : (function() {
        // append random number and time to ID
        var id = (Math.random()+''+(+new Date)).substring(2);
        document.write('<script id="wts' + id + '"></script>');
        return document.getElementById('wts' + id).
            previousSibling.src;
    })();
    function msg_parent(e) {
        // event handler for parent -> worker messages
    }
    function msg_worker(e) {
        // event handler for worker -> parent messages
    }
    function new_worker() {
        var w = new Worker(script_path);
        w.addEventListener('message', msg_worker, false);
        return w;
    }
    if (is_worker)
        global.addEventListener('message', msg_parent, false);

    // put the rest of your library here
    // to spawn a worker, use new_worker()
})(this);

আপনি দেখতে পাচ্ছেন, স্ক্রিপ্টটিতে পিতামাতার এবং শ্রমিকের দৃষ্টিভঙ্গি উভয়ের জন্য সমস্ত কোড রয়েছে, এটির নিজস্ব স্বতন্ত্র উদাহরণ কর্মী কিনা তা পরীক্ষা করে !document। কিছুটা অপ্রয়োজনীয় script_pathগণনা পিতা-মাতার পৃষ্ঠার তুলনায় স্ক্রিপ্টের পাথটি নির্ভুলভাবে গণনা করতে ব্যবহৃত হয়, যেহেতু সরবরাহিত পথটি new Workerস্ক্রিপ্ট নয়, পিতামাতার সাথে সম্পর্কিত।


4
আপনার সাইটটি নিখোঁজ হয়েছে বলে মনে হয়; আপনার কি নতুন ইউআরএল আছে?
ব্রায়ানফ্রেড

1
এটি একটি আকর্ষণীয় পদ্ধতির। এফডাব্লুআইডাব্লু, "ওয়েব" উইন্ডো "বনাম" "স্ব" (ওয়েব ওয়ার্কার বৈশ্বিক বস্তু) উপস্থিতি যাচাই করে আমি ওয়েব কর্মীদের বৈশিষ্ট্য সনাক্ত করি।
pwnall

পাপাপার্স কীভাবে ওয়েব ওয়ার্কার্সকে পরিচালনা করে তা আমি খতিয়ে দেখছি এবং তারা এই পদ্ধতিটি গ্রহণ করবে বলে মনে হচ্ছে github.com/mholt/PapaParse
জেপি

আমার মনে হয়, 'টাইপ অফ ইম্পোর্টস স্ক্রিপ্টস' ব্যবহার করে পরীক্ষা করা! == নাল 'বলতে পারে স্ক্রিপ্টটি কর্মীদের সুযোগে চলছে কিনা।
মেটিটিও

1
স্ক্রিপ্ট-উপাদান থেকে পূর্ববর্তী শিবলিঙ্গটি কী তা আমি বুঝতে পারি না। কেউ আমাকে ব্যাখ্যা করতে পারেন?
তিমোহ

28

Blobকর্মী কারখানার জন্য এটি সম্পর্কে পদ্ধতিটি ব্যবহার করে :

var BuildWorker = function(foo){
   var str = foo.toString()
             .match(/^\s*function\s*\(\s*\)\s*\{(([\s\S](?!\}$))*[\s\S])/)[1];
   return  new Worker(window.URL.createObjectURL(
                      new Blob([str],{type:'text/javascript'})));
}

সুতরাং আপনি এটি এভাবে ব্যবহার করতে পারেন ...

var myWorker = BuildWorker(function(){
   //first line of worker
   self.onmessage(){....};
   //last line of worker
});

সম্পাদনা করুন:

ক্রস-থ্রেড যোগাযোগ আরও সহজ করার জন্য আমি এই ধারণাটি আরও প্রসারিত করেছি: ব্রিজড-ওয়ার্কার.জেস

সম্পাদনা 2:

উপরের লিঙ্কটি আমি তৈরি একটি টুকরোটির জন্য। পরে অন্য কেউ এটিকে সত্যিকারের রেপোতে পরিণত করেছিলেন ।


11

ওয়েব কর্মীরা স্বতন্ত্র প্রোগ্রাম হিসাবে সম্পূর্ণ পৃথক প্রসঙ্গে কাজ করে।

এর অর্থ হ'ল কোডটি একটি প্রসঙ্গ থেকে অন্য বিষয়তে অন্য আকারে স্থানান্তরিত করা যাবে না, কারণ তারা তখন অন্য প্রসঙ্গে অন্তর্ভুক্ত ক্লোজারের মাধ্যমে অবজেক্টগুলিকে রেফারেন্স করতে সক্ষম হবে।
এটি বিশেষত গুরুত্বপূর্ণ কারণ ইস্কিমাস্ক্রিপ্টটি একক থ্রেডযুক্ত ভাষা হিসাবে তৈরি করা হয়েছে এবং ওয়েব কর্মীরা যেহেতু পৃথক থ্রেডে কাজ করে, আপনার তখন নন-থ্রেড-নিরাপদ ক্রিয়াকলাপ পরিচালিত হওয়ার ঝুঁকি থাকে।

এর আবার অর্থ হ'ল ওয়েব কর্মীদের উত্স আকারে কোড দিয়ে আরম্ভ করা দরকার।

বৈশিষ্ট থেকে WHATWG বলেছেন

যদি ফলস্বরূপ নিখুঁত URL এর উত্স এন্ট্রি স্ক্রিপ্টের উত্সের মতো না হয় তবে একটি SECURITY_ERR ব্যতিক্রম নিক্ষেপ করুন।

সুতরাং, স্ক্রিপ্টগুলি অবশ্যই মূল পৃষ্ঠার মতো একই স্কিমযুক্ত বাহ্যিক ফাইল হতে হবে: আপনি কোনও ডেটা: স্ক্রিপ্ট লোড করতে পারবেন না: URL বা জাভাস্ক্রিপ্ট: ইউআরএল, এবং একটি https: পৃষ্ঠাটি http: URL গুলি সহ স্ক্রিপ্টগুলি ব্যবহার করে শ্রমিকদের শুরু করতে পারেনি।

তবে দুর্ভাগ্যক্রমে এটি সত্যই ব্যাখ্যা করে না যে কেন একজন কেন কনস্ট্রাক্টরের কাছে সোর্স কোড সহ একটি স্ট্রিং পাস করার অনুমতি দিতে পারেনি।


6

একটি ইনলাইন কর্মী পড়া উপায় ভাল ..

    var worker_fn = function(e) 
    {
        self.postMessage('msg from worker');            
    };

    var blob = new Blob(["onmessage ="+worker_fn.toString()], { type: "text/javascript" });

    var worker = new Worker(window.URL.createObjectURL(blob));
    worker.onmessage = function(e) 
    {
       alert(e.data);
    };
    worker.postMessage("start"); 

আমি যা করেছি তা হ'ল আমি সমস্ত কর্মী কোড দিয়ে একটি ফাংশন তৈরি করেছি, সেই ফাংশনটি পাস করব toString(), শরীরটি এক্সট্রাক করব এবং তারপরে এটি একটি ব্লাবে রাখি। শেষ উত্তরে দেখুন, আমার একটি উদাহরণ আছে
ফার্নান্দো কারভাজাল

5

অ্যাড্রিয়ার প্রতিক্রিয়া নেওয়া এবং এটিকে একটি অনুলিপি-পাস্টেবল ফাংশনে রেখে দেওয়া যা বর্তমান ক্রোম এবং এফএফের সাথে কাজ করে তবে আইই 10 নয় (ব্লোব থেকে কর্মী সুরক্ষা ত্রুটির কারণ হয়ে থাকে )।

var newWorker = function (funcObj) {
    // Build a worker from an anonymous function body
    var blobURL = URL.createObjectURL(new Blob(
        ['(', funcObj.toString(), ')()'],
        {type: 'application/javascript'}
     ));

    var worker = new Worker(blobURL);

    // Won't be needing this anymore
    URL.revokeObjectURL(blobURL);

    return worker;
}

এবং এখানে একটি কার্যকারী উদাহরণ http://jsfiddle.net/ubershmekel/YYzvr/


5

সাম্প্রতিক উত্তর (2018)

আপনি গ্রিনলেট ব্যবহার করতে পারেন :

একটি অ্যাসিঙ্ক ফাংশনটিকে তার নিজের থ্রেডে সরান। ওয়ার্কারাইজের একটি সরলিকৃত একক-ফাংশন সংস্করণ ।

উদাহরণ:

import greenlet from 'greenlet'

const getName = greenlet(async username => {
  const url = `https://api.github.com/users/${username}`
  const res = await fetch(url)
  const profile = await res.json()
  return profile.name
})

console.log(await getName('developit'))

3

আপনার ব্যবহারের ক্ষেত্রে নির্ভর করে আপনি এর মতো কিছু ব্যবহার করতে পারেন

টাস্ক.জে সব সিওর (নোড.জেএস এবং ওয়েব) তে চালানোর জন্য সিপিইউ নিবিড় কোড পাওয়ার জন্য সরলীকৃত ইন্টারফেস

একটি উদাহরণ হবে

function blocking (exampleArgument) {
    // block thread
}

// turn blocking pure function into a worker task
const blockingAsync = task.wrap(blocking);

// run task on a autoscaling worker pool
blockingAsync('exampleArgumentValue').then(result => {
    // do something with result
});

2

ভি কে থ্রেড প্লাগইনটি একবার দেখুন। এইচটিআইএস প্লাগইন দিয়ে আপনি আপনার মূল কোডটিতে যে কোনও ফাংশন নিতে পারেন এবং এটি একটি থ্রেডে চালিত করতে পারেন (ওয়েব কর্মী)। সুতরাং, আপনার একটি বিশেষ "ওয়েব-কর্মী ফাইল" তৈরি করার দরকার নেই।

http://www.eslinstructor.net/vkthread/

--Vadim


1

আপনি ইনলাইন ওয়েব ওয়ার্কার্স ব্যবহার করে একই জাভাস্ক্রিপ্ট ফিতে ওয়েব কর্মীদের ব্যবহার করতে পারেন।

নীচের নিবন্ধটি আপনাকে ওয়েব ওয়ার্কার্স এবং তাদের সীমাবদ্ধতা এবং ওয়েব ওয়ার্কার্সগুলির ডিবাগিং সহজেই বোঝার জন্য সম্বোধন করবে।

ওয়েব ওয়ার্কার্সে দক্ষতা অর্জন করছে


1

আমি মনে করি এটি করার সর্বোত্তম উপায় হ'ল ব্লব অবজেক্টটি ব্যবহার করা, নীচে আপনি একটি সাধারণ উদাহরণ দেখতে পাচ্ছেন।

// create a Blob object with a worker code
var blob = new Blob(["onmessage = function(e) { postMessage('msg from worker'); }"]);

// Obtain a blob URL reference to our worker 'file'.
var blobURL = window.URL.createObjectURL(blob);

// create a Worker
var worker = new Worker(blobURL);
worker.onmessage = function(e) {
  console.log(e.data);
};
worker.postMessage("Send some Data"); 


1

এখানে কনসোল:

var worker=new Worker(window.URL.createObjectURL(new Blob([function(){
  //Long-running work here
  postMessage('done');
}.toString().split('\n').slice(1,-1).join('\n')],{type:'text/javascript'})));

worker.addEventListener('message',function(event){
  console.log(event.data);
});

1

https://developer.mozilla.org/es/docs/Web/Guide/Performance/Using_web_workers

    // Syntax: asyncEval(code[, listener])

var asyncEval = (function () {

  var aListeners = [], oParser = new Worker("data:text/javascript;charset=US-ASCII,onmessage%20%3D%20function%20%28oEvent%29%20%7B%0A%09postMessage%28%7B%0A%09%09%22id%22%3A%20oEvent.data.id%2C%0A%09%09%22evaluated%22%3A%20eval%28oEvent.data.code%29%0A%09%7D%29%3B%0A%7D");

  oParser.onmessage = function (oEvent) {
    if (aListeners[oEvent.data.id]) { aListeners[oEvent.data.id](oEvent.data.evaluated); }
    delete aListeners[oEvent.data.id];
  };


  return function (sCode, fListener) {
    aListeners.push(fListener || null);
    oParser.postMessage({
      "id": aListeners.length - 1,
      "code": sCode
    });
  };

})();


1

সুতরাং আমি মনে করি আমাদের কাছে এটির জন্য এখন অন্য একটি দুর্দান্ত বিকল্প রয়েছে, ES6 এ টেম্পলেট লিটারালসকে ধন্যবাদ। এটি আমাদের অতিরিক্ত কর্মী ফাংশন (এবং এর অদ্ভুত সুযোগ) নিয়ে বিতরণ করতে এবং কেবলমাত্র সেই পাঠ্যটি যে শ্রমিকের জন্য বহুমুখী পাঠ্য হিসাবে লেখা হয়েছিল তা লিখতে দেয়, অনেকটা এমন ক্ষেত্রে যেমন আমরা পাঠ্য সংরক্ষণ করার জন্য ব্যবহার করছিলাম তবে আসলে কোনও দলিল বা ডিওএমের প্রয়োজন ছাড়াই এটি করতে। উদাহরণ:

const workerScript = `
self.addEventListener('message', function(e) {
  var data = e.data;
  console.log('worker recieved: ',data);
  self.postMessage('worker added! :'+ addOne(data.value));
  self.close();//kills the worker
}, false);
`;

এই পদ্ধতির বাকী অংশটি এখানে একটি সংক্ষিপ্তসার ।

মনে রাখবেন যে আমরা যে কোনও অতিরিক্ত ক্রিয়াকলাপ নির্ভরতা টানতে পারি কর্মীর মধ্যে কেবল একটি অ্যারে সংগ্রহ করে এবং চালিয়ে যাওয়া to তাদের প্রতিটিকে স্ট্রিংয়ে কমানোর জন্য স্ট্রিং করুন (যতক্ষণ তারা ফাংশন ঘোষণা হিসাবে কাজ করা উচিত) এবং তারপরে কেবল এটি স্ক্রিপ্ট স্ট্রিংয়ে প্রিপেন্ডিং। এইভাবে আমাদের স্ক্রিপ্টগুলি আমদানি করতে হবে না যা আমরা ইতিমধ্যে লিখছি এমন কোডের ক্ষেত্রের মধ্যে বান্ডিল হয়ে থাকতে পারে।

এই নির্দিষ্ট সংস্করণের একমাত্র আসল ক্ষতি হ'ল লিটাররা পরিষেবা কর্মী কোডটি লিঙ্ক করতে সক্ষম হবে না (যেহেতু এটি কেবল একটি স্ট্রিং), এটি "পৃথক কর্মী ফাংশন পদ্ধতির জন্য একটি সুবিধা।"


1

এটি উপরের সাথে কেবল একটি সংযোজন - জেএসফিডেলে ওয়েব কর্মীদের পরীক্ষার জন্য আমার কাছে একটি দুর্দান্ত টেম্পলেট রয়েছে। ব্লবের চেয়ে এটি jsFiddles ?jsএপিআই ব্যবহার করে :

function workerFN() {
  self.onmessage = function(e) {
    switch(e.data.name) {
      case "" : 
      break;
      default:
        console.error("Unknown message:", e.data.name);
    }
  }
}
// This is a trick to generate real worker script that is loaded from server
var url = "/echo/js/?js="+encodeURIComponent("("+workerFN.toString()+")()");
var worker = new Worker(url);
worker.addEventListener("message", function(e) {
  switch(e.data.name) {
    case "" : 
    break;
    default:
      console.error("Unknown message:", e.data.name);
  }
})

সাধারণ ওয়েব কর্মী এবং ভাগ করা কর্মী টেম্পলেট উপলব্ধ।


1

আমি আবিষ্কার করেছি যে কোডপেন বর্তমানে ইনলাইন <script>ট্যাগগুলি type="text/javascript"( যাঁর কোনও ধরণের বৈশিষ্ট্য নেই) সিনট্যাক্স-হাইলাইট করে না ।

সুতরাং আমি লেবেলযুক্ত ব্লকগুলির সাহায্যে একটি অনুরূপ তবে কিছুটা আলাদা সমাধান তৈরি করেছি break, যা কেবলমাত্র <script>রাਪਰ ফাংশন তৈরি না করে আপনি কোনও ট্যাগ থেকে জামিন করতে পারেন (যা অপ্রয়োজনীয়)।

<!DOCTYPE html>
<script id="worker1">
  worker: { // Labeled block wrapper

    if (typeof window === 'object') break worker; // Bail if we're not a Worker

    self.onmessage = function(e) {
      self.postMessage('msg from worker');
    };
    // Rest of your worker code goes here.
  }
</script>
<script>
  var blob = new Blob([
    document.querySelector('#worker1').textContent
  ], { type: "text/javascript" })

  // Note: window.webkitURL.createObjectURL() in Chrome 10+.
  var worker = new Worker(window.URL.createObjectURL(blob));
  worker.onmessage = function(e) {
    console.log("Received: " + e.data);
  }
  worker.postMessage("hello"); // Start the worker.
</script>


1

একটি সাধারণ প্রচারিত সংস্করণ, Function#callAsWorkerএটি একটি আর্গ এবং আর্গুমেন্ট গ্রহণ করে (ঠিক যেমন call) এবং একটি প্রতিশ্রুতি দেয়:

Function.prototype.callAsWorker = function (...args) {
    return new Promise( (resolve, reject) => {
        const code = `self.onmessage = e => self.postMessage((${this.toString()}).call(...e.data));`,
            blob = new Blob([code], { type: "text/javascript" }),
            worker = new Worker(window.URL.createObjectURL(blob));
        worker.onmessage = e => (resolve(e.data), worker.terminate());
        worker.onerror = e => (reject(e.message), worker.terminate());
        worker.postMessage(args);
    });
}

// Demo
function add(...nums) {
    return nums.reduce( (a,b) => a+b );
}
// Let the worker execute the above function, with the specified arguments
add.callAsWorker(null, 1, 2, 3).then(function (result) {
    console.log('result: ', result);
});


close()আপনার ওয়েব কর্মী লাইফ হুক বন্ধ করার জন্য আপনার পদ্ধতি যুক্ত করা উচিত । বিকাশকারী.মোজিলা.আর.ইন-
শাহার ド ー ン লেভি

@ সাহার ド ー ン লেভি, closeফাংশনটি অবচিত করা হয়েছে। তবে শ্রমিকদের অবসান হতে পারে । আমি এখন যোগ করেছি।
ট্রিনকোট

0

আমি এই জাতীয় কোড ব্যবহার করি, আপনি আপনার অনমেজকে সাধারণ পাঠ্য ব্যতীত অন্য কোনও ফাংশন হিসাবে সংজ্ঞায়িত করতে পারেন, যাতে সম্পাদক আপনার কোড এবং jshint কাজ হাইলাইট করতে পারে।

const worker = createWorker();

createWorker() {
    const scriptContent = getWorkerScript();
    const blob = new Blob([
        scriptContent,
    ], {
        type: "text/javascipt"
    });
    const worker = new Worker(window.URL.createObjectURL(blob));
    return worker;
}

getWorkerScript() {
    const script = {
        onmessage: function (e) {
            console.log(e);
            let result = "Hello " + e.data
            postMessage(result);
        }
    };
    let content = "";
    for (let prop in script){
        content += `${prop}=${script[prop].toString()}`;
    }
    return content;
}


আমার উত্তরটি দেখুন , আমি কেবল এটি করেছি কিন্তু কলব্যাকগুলি কীভাবে পাস করবেন তা বিমূর্ত করার জন্য আমি একটি সম্পূর্ণ ক্লাস লিখেছিলাম
ফার্নান্দো কারভজাল

0

হ্যাঁ, এটি সম্ভব, আমি এটি ব্লব ফাইলগুলি ব্যবহার করে এবং একটি কলব্যাক পাস করেছিলাম

আমি আপনাকে দেখাব যে আমি কী ক্লাস লিখেছি এবং কীভাবে এটি ব্যাকগ্রাউন্ডে কলব্যাকগুলি সম্পাদন করে।

প্রথমে আপনি ক্যালব্যাকের যে GenericWebWorkerকোনও ডেটা যেটি প্রয়োগ করতে চান তা দিয়ে তাত্ক্ষণিকভাবে Web Workerব্যবহার করবেন যা এর মধ্যে আপনি ব্যবহার করতে চান এমন ফাংশন অন্তর্ভুক্ত করে , এক্ষেত্রে একটি নম্বর, একটি তারিখ এবং একটি ফাংশন বলেblocker

var worker = new GenericWebWorker(100, new Date(), blocker)

এই ব্লকার ফাংশনটি এন মিলিসেকেন্ডের জন্য অসীম কার্যকর করবে

function blocker (ms) {
    var now = new Date().getTime();
    while(true) {
        if (new Date().getTime() > now +ms)
            return;
    }   
}

এবং তারপরে আপনি এটি ব্যবহার করুন

worker.exec((num, date, fnBlocker) => {
    /*Everithing here does not block the main thread
      and this callback has access to the number, date and the blocker */
    fnBlocker(10000) //All of this run in backgrownd
    return num*10

}).then(d => console.log(d)) //Print 1000

এখন, নীচের উদাহরণে যাদুটি দেখার সময় হয়েছে

/*https://github.com/fercarvo/GenericWebWorker*/
class GenericWebWorker {
    constructor(...ags) {
        this.args = ags.map(a => (typeof a == 'function') ? {type:'fn', fn:a.toString()} : a)
    }

    async exec(cb) {
        var wk_string = this.worker.toString();
        wk_string = wk_string.substring(wk_string.indexOf('{') + 1, wk_string.lastIndexOf('}'));            
        var wk_link = window.URL.createObjectURL( new Blob([ wk_string ]) );
        var wk = new Worker(wk_link);

        wk.postMessage({ callback: cb.toString(), args: this.args });
 
        var resultado = await new Promise((next, error) => {
            wk.onmessage = e => (e.data && e.data.error) ? error(e.data.error) : next(e.data);
            wk.onerror = e => error(e.message);
        })

        wk.terminate(); window.URL.revokeObjectURL(wk_link);
        return resultado
    }

    async parallel(arr, cb) {
        var res = [...arr].map(it => new GenericWebWorker(it, ...this.args).exec(cb))
        var all = await Promise.all(res)
        return all
    }

    worker() {
        onmessage = async function (e) {
            try {                
                var cb = new Function(`return ${e.data.callback}`)();
                var args = e.data.args.map(p => (p.type == 'fn') ? new Function(`return ${p.fn}`)() : p);

                try {
                    var result = await cb.apply(this, args); //If it is a promise or async function
                    return postMessage(result)

                } catch (e) { throw new Error(`CallbackError: ${e}`) }
            } catch (e) { postMessage({error: e.message}) }
        }
    }
}


function blocker (ms) {
    var now = new Date().getTime();
    while(true) {
        if (new Date().getTime() > now +ms)
            return;
    }   
}

setInterval(()=> console.log("Not blocked " + Math.random()), 1000)

console.log("\n\nstarting blocking code in Worker\n\n")

var worker = new GenericWebWorker(100, new Date(), blocker)

worker.exec((num, date, fnBlocker) => {
    fnBlocker(7000) //All of this run in backgrownd
    return num*10    
})
.then(d => console.log(`\n\nEnd of blocking code: result ${d}\n\n`)) //Print 1000


0

আপনি আপনার کارکن.জেএস ফাইলের বিষয়বস্তু ব্যাকটিক্সের অভ্যন্তরে রাখতে পারেন (এটি একটি মাল্টলাইন স্ট্রিং ধ্রুবককে অনুমতি দেয়) এবং একটি ব্লব থেকে কর্মী তৈরি করতে পারেন:

var workerScript = `
    self.onmessage = function(e) {
        self.postMessage('message from worker');
    };
    // rest of worker code goes here
`;

var worker =
    new Worker(createObjectURL(new Blob([workerScript], { type: "text/javascript" })));

আপনি যদি কোনও কারণে কর্মীর জন্য পৃথক স্ক্রিপ্ট ট্যাগ রাখতে না চান তবে এটি সুবিধাজনক।


0

আর একটি সমাধান হ'ল কেবল কোনও ফাংশনে কর্মীকে জড়িয়ে রাখা, তারপরে একটি ফোঁড়া তৈরি করা যাতে ফাংশনটিকে অনুরোধ করা হয়:

     function workerCode() {
        self.onmessage = function (e) {
          console.log("Got message from parent", e.data);
        };
        setTimeout(() => {
          self.postMessage("Message From Worker");
        }, 2000);
      }

      let blob = new Blob([
        "(" + workerCode.toString() + ")()"
      ], {type: "text/javascript"});

      // Note: window.webkitURL.createObjectURL() in Chrome 10+.
      let worker = new Worker(window.URL.createObjectURL(blob));
      worker.onmessage = function (e) {
        console.log("Received: " + e.data);
      };
      worker.postMessage("hello"); // Start the worker.

-1

কর্মীদের মধ্যে ক্রিয়াকলাপ চালানোর জন্য এক-লাইনার:

const FunctionalWorker = fn => new Worker(window.URL.createObjectURL(new Blob(["(" + workerCode.toString() + ")()"], {type: "text/javascript"})));

ব্যবহারের উদাহরণ:

let fn = FunctionalWorker(() => {
    self.postMessage("hi");
});
fn.onmessage = msg => {
    console.log(msg);
};
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.