Utilizza richieste di intervallo per ottenere i dati dal server chunk di chunk e rimandalo al server chunk-by-chunk. Un esempio di utilizzo delle richieste di intervallo, basato su questa domanda SO è mostrata di seguito:
var chunkSize = 8388608; // for 8MB segments
function getPartialSegment(fileURL, chunkN, processData, whenError, prevreq){
var xmlhttp = prevreq || new XMLHttpRequest();
xmlhttp.open("GET", fileURL, true);
xmlhttp.setRequestHeader(
"Range",
"bytes=" + (chunkN*chunkSize) + "-" + ((chunkN+1)*chunkSize - 1)
);
xmlhttp.responseType = 'arraybuffer';
xmlhttp.onload = function(){
var response = xmlhttp.response;
if (response && (+xmlhttp.status === 200 || response.length > 0)){
if (response.byteLength%4){
if (!response.transfer){
var responseUint8 = new Uint8Array(response),
tmpDataBuffer=new ArrayBuffer(Math.floor(response.byteLength/4)*4+4),
tmpDataUint8 = new Uint8Array(tmpDataBuffer)
tmpDataUint8.set( responseUint8 );
processData(new Float32Array(tmpDataBuffer), xmlhttp)
} else processData(new Float32Array(ArrayBuffer.transfer(response,
Math.floor(response.byteLength/4)*4+4)),xmlhttp)
} else processData(new Float32Array(response), xmlhttp);
} else if (whenError instanceof Function)
whenError(xmlhttp.status, xmlhttp);
};
xmlhttp.send( null );
};
Tuttavia, per far funzionare questo metodo, è necessario configurare i server per accettare richieste di intervallo. Quindi, basato su questo altro post SO , puoi ottenere la dimensione del file remoto. Tuttavia, questo richiederà al tuo server di impostare l'intestazione content-length
sulla dimensione del file. Quindi, mettendo tutto insieme in un parser piccolo, ottieni qualcosa del genere (il seguente frammento di codice è completamente funzionale tranne che richiede getPartialSegment
sopra):
function proccessEntireFileInChunks(fileURL, processData, allDone, whenError){
var xmlhttp=new XMLHttpRequest();
xmlhttp.open("HEAD", fileURL, true);
xmlhttp.onload = function(){
var filelen = parseInt(xmlhttp.getResponseHeader("Content-Length"))
if (xmlhttp.status === 200 || !isNaN(filelen)){
var chunks = Math.ceil(filelen / chunkSize),
chunkN = 0;
if (!chunks) return allDone && allDone();
getPartialSegment(fileURL, chunkN, function nextFile(response){
processData(response, chunkN*chunkSize, filelen, xmlhttp);
if (++chunkN !== chunks){
getPartialSegment(fileURL, chunkN, nextFile, whenError, xmlhttp);
} else return allDone && allDone();
}, whenError, xmlhttp);
} else if (whenError instanceof Function)
whenError(xmlhttp.status, xmlhttp);
};
xmlhttp.send( null );
}
Detto questo, devo solo dire che se si aggiungono solo gli elementi, il server verrà tassato molto meno per aggiungerli sul server anziché sul client. Anch'io sono molto entusiasta di spostare il maggior numero possibile di elaborazioni sul client, ma l'invio di dati attraverso una rete solo per aggiunta è molto meno efficiente che aggiungendolo senza inviarlo attraverso una rete. Non sarei sorpreso se internamente aggiungesse un puntatore che è usato per leggere / scrivere tutti i byte nei dati alla richiesta di rete, il che significa che inviarlo attraverso la rete per ottenere aggiunto induce 3 aggiunte aggiuntive (minimo assoluto assoluto, sebbene probabilmente più in realtà) per byte nel tuo array sul server che avrebbe potuto essere solo una singola aggiunta per elemento sul server.