Direi di unire i dati in N righe prima di entrare in rapporti di calcolo. Rendere i rapporti di calcolo una singola funzione cioè. questa parte del programma // do some calculations...
lo promette utilizzando Q.
Dopo di che è possibile creare una serie di promesse ogni promessa è calculateRatiosForData(Nth row)
.
Successivamente è possibile effettuare una chiamata a Promise.all(yourArrayOfCalculateRatioPromises)
.
Il problema è che continuerai a calcolare tutti i dati sul browser. Se possibile, sarebbe meglio scaricare tale elaborazione sul server e utilizzare una richiesta POST
per l'elaborazione. La struttura delle promesse sembrerà sempre la stessa.
C'è anche il problema di decidere se sono necessari questi valori calcolati per il resto del copione. Se non sei bravo, se lo fai, incapsuleresti il resto dello script all'interno dello Promise.all(arrayOfPromises).then(function (result) { //rest of script}
. Il pezzo chiave di quel codice è lo .then (function() {}).
Suggerisco di utilizzare WebWorkers ma purtroppo non sono supportati da IE8. Ci sono soluzioni alternative trovate in google code e anche here ma non posso garantire per quanto bene funzioneranno queste opzioni.
EDIT: questo mostrerà come fare la promessa
Ci sono fondamentalmente due modi per farlo.
1) È possibile scrivere la funzione calculateRatios nello stile di un nodo indietro e poi promisify utilizzando D.
function calculateRatios (arrayInput, callback) {
//error checking if error
//callback(error)
//calculate the ratios algorithm then do
setTimeout(callback(undefined, data), 500);
}
E poi a promisify sarebbe simile a questa:
var Promise = require('q'), //however you want to do this in the browser
calculateRatiosAsync = Promise.promisify(calculateRatios);
Personalmente mi piace in questo modo perché è compatibile con altre librerie di controllo di flusso senza dover modificare la funzione originale, oppure puoi semplicemente usare la funzione originale nel modo in cui lo hai, se non è necessario prometterlo.
2) L'altro modo è creare esplicitamente una promessa.
var Promise = require('q'),
calculateRaiosAsync = function (input) {
var d = Promise.defer();
//do your error checking if error
d.reject();
//do your calclate ratios algorithm and store the data in a variable
setTimeout(d.resolve(yourFinishedData), 500);
//return your promise
return d.promise();
}
NOTA: Va notato che si dovrà richiedere la biblioteca promessa in modo diverso, ma lascio che a voi.
Ho letto http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-asynchronous-call?rq=1 ma sto davvero lottando per capire come per adattarlo al mio codice esistente. Ho un sacco di funzioni sincrone al di fuori di 'combineData', ho davvero bisogno di cambiarle tutte per essere asincrone? – Richard
c'è un modo per eseguire i rapporti di calcolo sul server? – RadleyMith
Dai un'occhiata a http://stackoverflow.com/q/6864397/1048572, http://stackoverflow.com/q/714942/1048572. E sì, dovrai cambiare tutto ciò che dipende dai risultati di ciò per gestire asincroni. – Bergi