वेब वर्कर की बुनियादी बातें

समस्या: JavaScript को एक ही समय पर दिखाने वाली समस्या

ऐसी कई परेशानियां हैं जो दिलचस्प ऐप्लिकेशन को पोर्ट किए जाने से रोकती हैं (जैसे, सर्वर-हैवी लागू करने से) क्लाइंट-साइड JavaScript में. इनमें ब्राउज़र के साथ काम करने की सुविधा, स्टैटिक टाइपिंग, सुलभता, और परफ़ॉर्मेंस शामिल हैं. अच्छी बात यह है कि ये टूल जल्द ही पुराने ज़माने की तरह होते जा रहे हैं, क्योंकि ब्राउज़र वेंडर तेज़ी से अपने JavaScript इंजन की स्पीड को बेहतर बनाते जा रहे हैं.

एक चीज़ जो JavaScript के लिए रुकावट बनी रही, वह है असल में भाषा. JavaScript एक सिंगल-थ्रेड एनवायरमेंट है. इसका मतलब है कि एक ही समय पर कई स्क्रिप्ट नहीं चलाई जा सकतीं. उदाहरण के तौर पर, एक ऐसी साइट की कल्पना करें जिसे यूज़र इंटरफ़ेस (यूआई) इवेंट को हैंडल करने, क्वेरी करने, और बड़ी संख्या में एपीआई डेटा को प्रोसेस करने, और डीओएम में बदलाव करने की ज़रूरत होती है. बहुत आम है, है न? माफ़ करें, ब्राउज़र के JavaScript रनटाइम में सीमाओं की वजह से, ये सभी काम एक साथ नहीं किए जा सकते. स्क्रिप्ट एक ही थ्रेड में होती है.

डेवलपर setTimeout(), setInterval(), XMLHttpRequest, और इवेंट हैंडलर जैसी तकनीकों का इस्तेमाल करके 'एक साथ काम करने वाली चीज़ों' की नकल करते हैं. हां, ये सभी सुविधाएं एसिंक्रोनस रूप से चलती हैं. हालांकि, ब्लॉक न करने का मतलब यह नहीं है कि एक साथ काम करता रहेगा. एसिंक्रोनस इवेंट प्रोसेस होने के बाद ही मौजूदा स्क्रिप्ट लागू हो जाती है. अच्छी ख़बर यह है कि HTML5 हमें इन हैक से बेहतर कुछ देता है!

पेश है Web Workers: JavaScript में थ्रेडिंग की सुविधा

वेब वर्कर स्पेसिफ़िकेशन में, आपके वेब ऐप्लिकेशन में बैकग्राउंड स्क्रिप्ट को जनरेट करने वाले एपीआई के बारे में जानकारी दी जाती है. वेब वर्कर की मदद से, कई काम किए जा सकते हैं. जैसे- उपयोगकर्ता के इंटरैक्शन को मैनेज करने के लिए यूज़र इंटरफ़ेस (यूआई) या अन्य स्क्रिप्ट को ब्लॉक किए बिना, लंबे समय तक चलने वाली स्क्रिप्ट को ट्रिगर करना. वे उस 'खराब स्क्रिप्ट' वाले डायलॉग को लिखने और खत्म करने में मदद करेंगे जिसे हम सभी पसंद करते हैं:

जवाब न देने वाली स्क्रिप्ट का डायलॉग बॉक्स
स्क्रिप्ट का सामान्य जवाब न देने वाला डायलॉग बॉक्स.

एक जैसे काम करने के लिए, वर्कर थ्रेड जैसे मैसेज पास करने की सुविधा का इस्तेमाल करते हैं. ये आपके यूज़र इंटरफ़ेस (यूआई) को रीफ़्रेश, बेहतर परफ़ॉर्मेंस देने वाले, और उपयोगकर्ताओं के लिए रिस्पॉन्सिव बनाए रखने के लिए बेहतरीन हैं.

वेब वर्कर के टाइप

ध्यान दें कि जानकारी में दो तरह के वेब वर्कर, काम पर काम करने वाले लोग और शेयर किए गए वर्कर के बारे में बात की गई है. इस लेख में, सिर्फ़ उन कर्मचारियों के बारे में जानकारी दी गई है जो काम करते हैं. मैं हर बार उन्हें 'वेब वर्कर' या 'कर्मचारी' कहूँगी.

YouTube TV का इस्तेमाल शुरू करना

वेब वर्कर किसी आइसोलेटेड थ्रेड में चलते हैं. इस वजह से, उनके ज़रिए चलाए जाने वाले कोड को एक अलग फ़ाइल में शामिल किया जाना चाहिए. हालांकि, ऐसा करने से पहले, अपने मुख्य पेज पर एक नया Worker ऑब्जेक्ट बनाएं. कंस्ट्रक्टर, वर्कर स्क्रिप्ट का नाम लेता है:

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

अगर बताई गई फ़ाइल मौजूद है, तो ब्राउज़र एक नया वर्कर थ्रेड बनाएगा, जिसे एसिंक्रोनस तरीके से डाउनलोड किया जाएगा. जब तक फ़ाइल पूरी तरह डाउनलोड और एक्ज़ीक्यूट नहीं हो जाती, तब तक वर्कर शुरू नहीं होगा. अगर आपके वर्कर का पाथ 404 दिखाता है, तो वर्कर काम नहीं करेगा.

वर्कर बनाने के बाद, इसे postMessage() तरीके से कॉल करके शुरू करें:

worker.postMessage(); // Start the worker.

मैसेज पास सुविधा का इस्तेमाल करके, किसी कर्मचारी से बातचीत करना

इवेंट मॉडल और postMessage() तरीके का इस्तेमाल करके, काम और उसके पैरंट पेज के बीच कम्यूनिकेशन किया जाता है. आपके ब्राउज़र/वर्शन के आधार पर, postMessage() किसी स्ट्रिंग या JSON ऑब्जेक्ट को अपने सिंगल तर्क के तौर पर स्वीकार कर सकता है. आधुनिक ब्राउज़र के सबसे नए वर्शन में, JSON ऑब्जेक्ट पास करने की सुविधा काम करती है.

नीचे doWork.js में किसी वर्कर को 'नमस्ते दुनिया' पास करने के लिए स्ट्रिंग का इस्तेमाल करने का उदाहरण दिया गया है. वर्कर सिर्फ़ उस मैसेज को दिखाता है जो उसे भेजा गया है.

मुख्य स्क्रिप्ट:

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

worker.addEventListener('message', function(e) {
console.log('Worker said: ', e.data);
}, false);

worker.postMessage('Hello World'); // Send data to our worker.

doWork.js (कर्मी):

self.addEventListener('message', function(e) {
self.postMessage(e.data);
}, false);

जब मुख्य पेज से postMessage() को कॉल किया जाता है, तो हमारा वर्कर message इवेंट के लिए onmessage हैंडलर तय करके उस मैसेज को मैनेज करता है. मैसेज पेलोड (इस मामले में 'नमस्ते दुनिया') को Event.data में ऐक्सेस किया जा सकता है. यह उदाहरण ज़्यादा दिलचस्प नहीं है, लेकिन इससे पता चलता है कि postMessage() से, मुख्य थ्रेड में डेटा वापस भेजा जा सकता है. सुविधाजनक!

मुख्य पेज और वर्कर के बीच पास किए गए मैसेज कॉपी किए जाते हैं, शेयर नहीं किए जाते. उदाहरण के लिए, अगले उदाहरण में JSON मैसेज की 'msg' प्रॉपर्टी को दोनों जगहों से ऐक्सेस किया जा सकता है. ऐसा लगता है कि ऑब्जेक्ट को सीधे वर्कर को पास किया जा रहा है. भले ही, वह किसी अलग जगह पर चल रहा हो. असल में, क्या हो रहा है कि ऑब्जेक्ट को, वर्कर के हाथों में दिए जाने के बाद, क्रम से लगाया जा रहा है. इसके बाद, ऑब्जेक्ट को क्रम से लगाया जा रहा है. पेज और वर्कर एक ही इंस्टेंस को शेयर नहीं करते. इसलिए, हर पास पर एक डुप्लीकेट बन जाता है. ज़्यादातर ब्राउज़र, इस सुविधा को अपने-आप JSON एन्कोडिंग/डिकोड करके लागू करते हैं.

नीचे दिया गया उदाहरण, JSON ऑब्जेक्ट का इस्तेमाल करके मैसेज पास करना ज़्यादा मुश्किल है.

मुख्य स्क्रिप्ट:

<button onclick="sayHI()">Say HI</button>
<button onclick="unknownCmd()">Send unknown command</button>
<button onclick="stop()">Stop worker</button>
<output id="result"></output>

<script>
function sayHI() {
worker.postMessage({'cmd': 'start', 'msg': 'Hi'});
}

function stop() {
// worker.terminate() from this script would also stop the worker.
worker.postMessage({'cmd': 'stop', 'msg': 'Bye'});
}

function unknownCmd() {
worker.postMessage({'cmd': 'foobard', 'msg': '???'});
}

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

worker.addEventListener('message', function(e) {
document.getElementById('result').textContent = e.data;
}, false);
</script>

doWork2.js:

self.addEventListener('message', function(e) {
var data = e.data;
switch (data.cmd) {
case 'start':
    self.postMessage('WORKER STARTED: ' + data.msg);
    break;
case 'stop':
    self.postMessage('WORKER STOPPED: ' + data.msg +
                    '. (buttons will no longer work)');
    self.close(); // Terminates the worker.
    break;
default:
    self.postMessage('Unknown command: ' + data.msg);
};
}, false);

ट्रांसफ़र किए जा सकने वाले ऑब्जेक्ट

ज़्यादातर ब्राउज़र स्ट्रक्चर्ड क्लोनिंग एल्गोरिदम का इस्तेमाल करते हैं. इससे आपको वर्कर के अंदर या बाहर, ज़्यादा जटिल टाइप पास करने की सुविधा मिलती है. जैसे, File, Blob, ArrayBuffer, और JSON ऑब्जेक्ट. हालांकि, postMessage() का इस्तेमाल करके इस तरह का डेटा पास करने पर भी, एक कॉपी बनाई जाती है. इसलिए, अगर 50 एमबी की बड़ी फ़ाइल पास की जा रही है (उदाहरण के लिए), तो उस फ़ाइल को वर्कर और मुख्य थ्रेड के बीच में लाने-ले जाने में ज़्यादा समय लगता है.

स्ट्रक्चर्ड क्लोनिंग बेहतरीन काम है, लेकिन एक कॉपी में सैकड़ों मिलीसेकंड लग सकते हैं. परफ़ हिट से निपटने के लिए, ट्रांसफ़र किए जा सकने वाले ऑब्जेक्ट का इस्तेमाल करें.

ट्रांसफ़र किए जा सकने वाले ऑब्जेक्ट की मदद से, डेटा को एक कॉन्टेक्स्ट से दूसरे कॉन्टेक्स्ट में ट्रांसफ़र किया जाता है. यह ज़ीरो-कॉपी है. इससे किसी वर्कर को डेटा भेजने की परफ़ॉर्मेंस काफ़ी बेहतर हो जाती है. अगर आप C/C++ दुनिया से हैं, तो इसे पास-दर-रेफ़रंस के तौर पर देखें. हालांकि, पास-बाय-रेफ़रंस के उलट, नए कॉन्टेक्स्ट में ट्रांसफ़र करने के बाद, कॉल करने के कॉन्टेक्स्ट का 'वर्शन' उपलब्ध नहीं होता. उदाहरण के लिए, किसी ArrayBuffer को मुख्य ऐप्लिकेशन से वर्कर पर ट्रांसफ़र करते समय, मूल ArrayBuffer मिटा दिया जाता है और अब इसका इस्तेमाल नहीं किया जा सकता. इसकी सामग्री को (शाब्दिक रूप से) वर्कर के संदर्भ में ट्रांसफ़र कर दिया जाता है.

ट्रांसफ़र किए जा सकने वाले ऑब्जेक्ट का इस्तेमाल करने के लिए, postMessage() के थोड़े अलग हस्ताक्षर का इस्तेमाल करें:

worker.postMessage(arrayBuffer, [arrayBuffer]);
window.postMessage(arrayBuffer, targetOrigin, [arrayBuffer]);

वर्कर केस, पहला तर्क डेटा होता है और दूसरा तर्क उन आइटम की सूची होता है जिन्हें ट्रांसफ़र किया जाना चाहिए. वैसे तो पहले तर्क में ArrayBuffer होना ज़रूरी नहीं है. उदाहरण के लिए, यह एक JSON ऑब्जेक्ट हो सकता है:

worker.postMessage({data: int8View, moreData: anotherBuffer},
                [int8View.buffer, anotherBuffer]);

अहम पॉइंट यह है: दूसरा आर्ग्युमेंट ArrayBuffers का कलेक्शन होना चाहिए. ट्रांसफ़र किए जा सकने वाले आइटम की सूची यहां दी गई है.

ट्रांसफ़रेबल के बारे में ज़्यादा जानकारी के लिए, developer.chrome.com पर हमारी पोस्ट देखें.

कर्मचारियों का माहौल

वर्कर स्कोप

वर्कर के संदर्भ में, self और this दोनों, वर्कर के ग्लोबल स्कोप का रेफ़रंस देते हैं. इसलिए, पिछले उदाहरण को इस तरह भी लिखा जा सकता है:

addEventListener('message', function(e) {
var data = e.data;
switch (data.cmd) {
case 'start':
    postMessage('WORKER STARTED: ' + data.msg);
    break;
case 'stop':
...
}, false);

इसके अलावा, आपके पास onmessage इवेंट हैंडलर को सीधे सेट करने का विकल्प भी है (हालांकि, addEventListener को हमेशा JavaScript निंजा, बढ़ावा देता है).

onmessage = function(e) {
var data = e.data;
...
};

कर्मचारियों के लिए उपलब्ध सुविधाएं

अपने मल्टीथ्रेड व्यवहार की वजह से, वेब वर्कर के पास JavaScript की सुविधाओं के सिर्फ़ सबसेट का ऐक्सेस होता है:

  • navigator ऑब्जेक्ट
  • location ऑब्जेक्ट (रीड-ओनली ऐक्सेस)
  • XMLHttpRequest
  • setTimeout()/clearTimeout() और setInterval()/clearInterval()
  • ऐप्लिकेशन की कैश मेमोरी
  • importScripts() तरीके का इस्तेमाल करके, बाहरी स्क्रिप्ट इंपोर्ट करना
  • अन्य वेब वर्कर देना

कर्मचारियों के पास इनका ऐक्सेस नहीं है:

  • डीओएम (इसमें थ्रेड का इस्तेमाल करने की सुविधा नहीं है)
  • window ऑब्जेक्ट
  • document ऑब्जेक्ट
  • parent ऑब्जेक्ट

बाहरी स्क्रिप्ट लोड हो रही हैं

importScripts() फ़ंक्शन की मदद से, किसी वर्कर में बाहरी स्क्रिप्ट फ़ाइलें या लाइब्रेरी लोड की जा सकती हैं. यह तरीका इंपोर्ट किए जाने वाले संसाधनों के फ़ाइल नाम दिखाने वाली शून्य या उससे ज़्यादा स्ट्रिंग लेता है.

यह उदाहरण script1.js और script2.js को वर्कर में लोड करता है:

worker.js:

importScripts('script1.js');
importScripts('script2.js');

इसे एक इंपोर्ट स्टेटमेंट के रूप में भी लिखा जा सकता है:

importScripts('script1.js', 'script2.js');

सबवर्क

मज़दूरों में बाल मज़दूरों को पैदा करने की क्षमता है. रनटाइम के दौरान, बड़े टास्क को और ज़्यादा हिस्सों में बांटने के लिए यह बहुत बढ़िया है. हालांकि, सब-वर्कर के लिए कुछ चेतावनियां होती हैं:

  • सब-वर्कर को उसी ऑरिजिन में होस्ट किया जाना चाहिए जो पैरंट पेज में है.
  • सब-वर्कर के यूआरआई का समाधान उनके पैरंट वर्कर की जगह के हिसाब से किया जाता है (मुख्य पेज के उलट).

इस बात का ध्यान रखें कि ज़्यादातर ब्राउज़र हर वर्कर के लिए अलग प्रोसेस जनरेट करते हैं. किसी कर्मचारी के फ़ार्म को पैदा करने से पहले, उसका इस्तेमाल करने से पहले, उपयोगकर्ता के सिस्टम के कई संसाधनों को इस्तेमाल करने को लेकर सावधान रहें. इसकी एक वजह यह है कि मुख्य पेजों और वर्कर के बीच पास किए गए मैसेज को कॉपी किया जाता है, शेयर नहीं किया जाता. देखें कि मैसेज पासिंग की मदद से, किसी वर्कर से कैसे बात की जा रही है.

सबवर्कर को जन्म देने के तरीके के सैंपल के लिए, स्पेसिफ़िकेशन में यह उदाहरण देखें.

इनलाइन वर्कर

अगर आपको तुरंत अपनी वर्कर स्क्रिप्ट बनानी है या अलग-अलग वर्कर फ़ाइलें बनाए बिना, खुद से पूरा पेज बनाना है, तो क्या होगा? Blob() की मदद से, वर्कर कोड को स्ट्रिंग के तौर पर एक यूआरएल हैंडल बनाकर, अपने वर्कर को मुख्य लॉजिक वाली एचटीएमएल फ़ाइल में "इनलाइन" किया जा सकता है:

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);

var worker = new Worker(blobURL);
worker.onmessage = function(e) {
// e.data == 'msg from worker'
};
worker.postMessage(); // Start the worker.

ब्लॉब यूआरएल

यह सुविधा window.URL.createObjectURL() के कॉल के साथ मिलती है. यह तरीका एक आसान यूआरएल स्ट्रिंग बनाता है. इसका इस्तेमाल, DOM File या Blob ऑब्जेक्ट में सेव किए गए डेटा का रेफ़रंस देने के लिए किया जा सकता है. उदाहरण के लिए:

blob:http://localhost/c745ef73-ece9-46da-8f66-ebes574789b1

ब्लॉब यूआरएल यूनीक होते हैं और आपके ऐप्लिकेशन के हमेशा तक चलते रहते हैं (उदाहरण के लिए, document अनलोड होने तक). अगर कई Blob यूआरएल बनाए जा रहे हैं, तो बेहतर होगा कि आप उन रेफ़रंस को छोड़ दें जिनकी अब ज़रूरत नहीं है. आप ब्लॉब यूआरएल को window.URL.revokeObjectURL() को पास करके, उसे सीधे तौर पर रिलीज़ कर सकते हैं:

window.URL.revokeObjectURL(blobURL);

Chrome में, सभी बनाए गए ब्लॉब यूआरएल को देखने के लिए एक अच्छा पेज दिया गया है: chrome://blob-internals/.

पूरा उदाहरण

इससे एक कदम आगे बढ़ते हुए, हमने ज़्यादा समझदारी से यह काम किया है कि हमारे पेज में वर्कर के JS कोड को किस तरह इनलाइन किया गया है. यह तकनीक वर्कर की जानकारी देने के लिए <script> टैग का इस्तेमाल करती है:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>

<div id="log"></div>

<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>
function log(msg) {
    // Use a fragment: browser will only render/reflow once.
    var fragment = document.createDocumentFragment();
    fragment.appendChild(document.createTextNode(msg));
    fragment.appendChild(document.createElement('br'));

    document.querySelector("#log").appendChild(fragment);
}

var blob = new Blob([document.querySelector('#worker1').textContent]);

var worker = new Worker(window.URL.createObjectURL(blob));
worker.onmessage = function(e) {
    log("Received: " + e.data);
}
worker.postMessage(); // Start the worker.
</script>
</body>
</html>

मेरी राय में, यह नया तरीका थोड़ा साफ़ है और पढ़ने में ज़्यादा आसान है. यह id="worker1" और type='javascript/worker' के साथ स्क्रिप्ट टैग को तय करता है (इसलिए, ब्राउज़र JS को पार्स नहीं करता). उस कोड को document.querySelector('#worker1').textContent का इस्तेमाल करके स्ट्रिंग के तौर पर एक्सट्रैक्ट किया जाता है और फ़ाइल बनाने के लिए Blob() को पास कर दिया जाता है.

बाहरी स्क्रिप्ट लोड हो रही हैं

अपने वर्कर कोड को इनलाइन करने के लिए इन तकनीकों का इस्तेमाल करते समय, importScripts() सिर्फ़ तब काम करेगा, जब आप एक पूरा यूआरआई दें. अगर किसी रिलेटिव यूआरआई को पास करने की कोशिश की जाती है, तो ब्राउज़र सुरक्षा से जुड़ी गड़बड़ी की शिकायत करेगा. इसकी वजह: वर्कर (अब ब्लॉब यूआरएल से बनाया गया है) का समाधान blob: प्रीफ़िक्स से किया जाएगा, जबकि आपका ऐप्लिकेशन किसी दूसरी (शायद http://) स्कीम से चलेगा. इसलिए, क्रॉस ऑरिजिन की पाबंदियों की वजह से ऐसा नहीं हो पाएगा.

किसी इनलाइन वर्कर में importScripts() को इस्तेमाल करने का एक तरीका यह है कि अपनी मुख्य स्क्रिप्ट के मौजूदा यूआरएल को "इंजेक्ट" किया जाए, ताकि उसे इनलाइन वर्कर को पास किया जा सके और मैन्युअल रूप से पूरा यूआरएल बनाया जा सके. इससे यह पक्का होगा कि बाहरी स्क्रिप्ट उसी ऑरिजिन से इंपोर्ट की गई है. मान लें कि आपका मुख्य ऐप्लिकेशन http://example.com/index.html से चल रहा है:

...
<script id="worker2" type="javascript/worker">
self.onmessage = function(e) {
var data = e.data;

if (data.url) {
var url = data.url.href;
var index = url.indexOf('index.html');
if (index != -1) {
    url = url.substring(0, index);
}
importScripts(url + 'engine.js');
}
...
};
</script>
<script>
var worker = new Worker(window.URL.createObjectURL(bb.getBlob()));
worker.postMessage(<b>{url: document.location}</b>);
</script>

गड़बड़ियों को ठीक करना

किसी भी अन्य JavaScript लॉजिक की तरह ही, हो सकता है कि आप अपने वेब वर्कर में अपलोड की गई किसी भी गड़बड़ी को हैंडल करना चाहें. अगर किसी वर्कर को लागू करते समय कोई गड़बड़ी होती है, तो ErrorEvent ट्रिगर होता है. इंटरफ़ेस में तीन उपयोगी प्रॉपर्टी होती हैं, जिनकी मदद से गड़बड़ी का पता लगाया जा सकता है: filename - गड़बड़ी की वजह वाली वर्कर स्क्रिप्ट का नाम, lineno - वह लाइन नंबर जहां गड़बड़ी हुई, और message - गड़बड़ी का सही ब्यौरा. गड़बड़ी वाली प्रॉपर्टी को प्रिंट करने के लिए, onerror इवेंट हैंडलर सेट अप करने का एक उदाहरण यहां दिया गया है:

<output id="error" style="color: red;"></output>
<output id="result"></output>

<script>
function onError(e) {
document.getElementById('error').textContent = [
    'ERROR: Line ', e.lineno, ' in ', e.filename, ': ', e.message
].join('');
}

function onMsg(e) {
document.getElementById('result').textContent = e.data;
}

var worker = new Worker('workerWithError.js');
worker.addEventListener('message', onMsg, false);
worker.addEventListener('error', onError, false);
worker.postMessage(); // Start worker without a message.
</script>

उदाहरण: workspaceWithError.js, 1/x करने की कोशिश करता है, जहां x की वैल्यू नहीं बताई गई है.

// TODO: DevSite - कोड सैंपल को हटा दिया गया, क्योंकि उसमें इनलाइन इवेंट हैंडलर का इस्तेमाल किया गया था

workerWithError.js:

self.addEventListener('message', function(e) {
postMessage(1/x); // Intentional error.
};

सुरक्षा के बारे में जानकारी

लोकल ऐक्सेस से जुड़ी पाबंदियां

Google Chrome की सुरक्षा से जुड़ी पाबंदियों की वजह से, वर्कर को ब्राउज़र के सबसे नए वर्शन में स्थानीय तौर पर (जैसे, file:// से) नहीं चलाया जाएगा. इसकी जगह, वे चुपचाप हार गए! file:// स्कीम से अपने ऐप्लिकेशन को चलाने के लिए, --allow-file-access-from-files फ़्लैग सेट के साथ Chrome चलाएं.

अन्य ब्राउज़र समान प्रतिबंध लागू नहीं करते.

एक ही मूल वजह

वर्कर स्क्रिप्ट, बाहरी फ़ाइलें होनी चाहिए, जिनकी स्कीम उनके कॉलिंग पेज के जैसी ही हो. इस वजह से, data: यूआरएल या javascript: यूआरएल से स्क्रिप्ट लोड नहीं की जा सकती. साथ ही, https: पेज भी http: यूआरएल से शुरू होने वाली वर्कर स्क्रिप्ट को शुरू नहीं कर सकता.

इस्तेमाल के उदाहरण

किस तरह का ऐप्लिकेशन वेब वर्कर का इस्तेमाल करेगा? दिमागी कसरत कराने के लिए यहां कुछ और आइडिया दिए गए हैं:

  • बाद में इस्तेमाल के लिए, डेटा को प्रीफ़ेच करना और/या कैश मेमोरी में सेव करना.
  • कोड सिंटैक्स हाइलाइट करने की सुविधा या टेक्स्ट की अन्य रीयल-टाइम फ़ॉर्मैटिंग.
  • स्पेल-चेकर.
  • वीडियो या ऑडियो डेटा का विश्लेषण करना.
  • बैकग्राउंड I/O या वेबसेवाओं की पोलिंग.
  • बड़े पैमाने पर डेटा का कलेक्शन या JSON फ़ाइल के बड़े जवाबों को प्रोसेस किया जा रहा है.
  • <canvas> में इमेज फ़िल्टर की जा रही है.
  • लोकल वेब डेटाबेस की कई लाइनों को अपडेट किया जा रहा है.

Web Workers API से जुड़े इस्तेमाल के उदाहरणों के बारे में ज़्यादा जानकारी के लिए, वर्कर की खास जानकारी देखें.

डेमो

रेफ़रंस