Un esempio vale più di mille parole…:
pagina.html:
codice:
<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Esempio</title>
<script type="text/javascript">
function faiQualcosa (oggetto) {
/* Qui arriveranno un po' alla volta i dati. In quest'esempio c'e' un alert. Nella tua pagina invece li lavorerai con le tue librerie. */
alert(oggetto.glossary.title);
}
var retrieveJSON = (function () {
function switchMsg (oEvent) {
if (oEvent.data === 0) {
alert("Ok, ho letto tutto correttamente. Chiudo il worker.");
this.terminate();
return;
}
if (isFinite(oEvent.data) && oEvent.data > 0) {
this.terminate();
if (confirm("Errore sconosciuto. Vuoi riprovare?")) {
initWorker();
}
return;
}
faiQualcosa(oEvent.data);
this.postMessage("continua");
}
function initWorker () {
oReader = new Worker("getjson.js");
oReader.onmessage = switchMsg;
}
var oReader;
return initWorker;
})();
onload = retrieveJSON;
</script>
</head>
<body>
</body>
</html>
getjson.js:
codice:
function switchMsg (oEvent) {
/* Decommenta la linea seguente se vuoi generare un errore ogni tanto per il debug. Quando avrai finito cancella pure questo commento. */
/* if (Math.floor(Math.random() * 3) === 2) { postMessage(1); return; } */
if (oEvent.data === "continua") {
nextDispatch();
}
}
function getData () {
oMyData = JSON.parse(this.responseText);
nextDispatch();
}
function switchError (oErr) {
/* Se vuoi raffinare la gestione degli errori, invia un numero maggiore di zero univoco a seconda di oErr... */
postMessage(1);
}
function nextDispatch () {
if (!oMyData) { return; }
if (nIdx >= oMyData.length) {
postMessage(0);
return;
}
postMessage(oMyData[nIdx++]);
}
var
oMyData, nIdx = 0, oReq = new XMLHttpRequest();
onmessage = switchMsg;
onerror = switchError;
oReq.onload = getData;
oReq.onerror = switchError;
oReq.open("get", "tuofile.json", true);
oReq.send();
tuofile.json:
codice:
[
{
"glossary": {
"title": "example glossary #1",
"GlossDiv": {
"title": "S",
"GlossList": {
"GlossEntry": {
"ID": "SGML",
"SortAs": "SGML",
"GlossTerm": "Standard Generalized Markup Language",
"Acronym": "SGML",
"Abbrev": "ISO 8879:1986",
"GlossDef": {
"para": "A meta-markup language, used to create markup languages such as DocBook.",
"GlossSeeAlso": ["GML", "XML"]
},
"GlossSee": "markup"
}
}
}
}
}, {
"glossary": {
"title": "example glossary #2",
"GlossDiv": {
"title": "S",
"GlossList": {
"GlossEntry": {
"ID": "SGML",
"SortAs": "SGML",
"GlossTerm": "Standard Generalized Markup Language",
"Acronym": "SGML",
"Abbrev": "ISO 8879:1986",
"GlossDef": {
"para": "A meta-markup language, used to create markup languages such as DocBook.",
"GlossSeeAlso": ["GML", "XML"]
},
"GlossSee": "markup"
}
}
}
}
}, {
"glossary": {
"title": "example glossary #3",
"GlossDiv": {
"title": "S",
"GlossList": {
"GlossEntry": {
"ID": "SGML",
"SortAs": "SGML",
"GlossTerm": "Standard Generalized Markup Language",
"Acronym": "SGML",
"Abbrev": "ISO 8879:1986",
"GlossDef": {
"para": "A meta-markup language, used to create markup languages such as DocBook.",
"GlossSeeAlso": ["GML", "XML"]
},
"GlossSee": "markup"
}
}
}
}
}
]
Come vedi una parte del tuo lavoro consisterà nel decidere come spezzettare i dati. Il mio JSON di esempio è un array di tre elementi, quindi è facile spezzettarlo in tre invii. La funzione che se ne occupa è nextDispatch().
Io non so com'è fatto il tuo file JSON, in ogni caso dovrai trovare un modo per spezzettarlo. Il punto non è il tempo che ci impieghi a leggere i dati, ma è il tempo che impieghi a riempire i grafici. E il worker sta lì ad aspettare che tu abbia finito prima di inviare un secondo pacchetto di dati. Spero sia tutto chiaro.
Originariamente inviato da Jey
Nel worker quindi non mi serve fare la richiesta dei dati al server, ma la parte di creazione dei div e del grafico...
E' possibile o non c'è scampo??? xD
No. il worker non può accedere al DOM della pagina principale. Ma spero ti sia chiaro che non è necessario. 
P.S. La gestione degli errori qui è grossolana: per qualsiasi tipo di errore riavvio il worker. Tu però puoi decidere di raffinarla inviando un codice numerico diverso a seconda del tipo di errore e, per esempio, nel caso di errore nella lettura del file puoi semplicemente far ripartire solamente AJAX invece dell'intero worker. Ma si tratta di sottigliezze: generalmente gli errori non ci dovrebbero proprio essere!
Oppure puoi decidere di rimuovere del tutto la gestione degli errori.