2015-08-25 5 views
6

Ich arbeite mit einer datenintensiven Website und ich muss IE8 unterstützen. Ich bekomme einige "langsam laufende Skript" -Fehler in IE8, also passe ich meinen Code an, um periodisch während Schleifen für ältere Browser anzuhalten.JavaScript: Passen Sie synchronen Code async an, um IE8 zu unterstützen?

Dies ist mein aktueller Code:

combineData: function(xData, yData, values) { 
    var combinedData = this.combineDatasets(xData, yData, values.x, values.x_val); 
    combinedData = this.calculateRatiosForData(combinedData); 
    // various other data operations, then continue to set up chart... 
}, 

calculateRatiosForData: function(data, isSpecialDenominator, x_val_key) { 
    _.each(data, function(d, i) { 
     // do some calculations... 
    }); 
    return data; 
}, 

Wie kann ich calculateRatiosForData anpassen N Zeilen gleichzeitig zu verarbeiten, dann Pause?

Dies wird es asynchron machen, und ich habe Schwierigkeiten, meinen Code anzupassen, um damit umzugehen.

Was auch immer ich mache, muss natürlich in IE8 unterstützt werden!

+0

Ich habe http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-asynchronous-call?rq=1 gelesen, aber ich habe wirklich Mühe zu verstehen, wie um es an meinen bestehenden Code anzupassen. Ich habe viele synchrone Funktionen außerhalb von 'combineData', muss ich wirklich alle asynchron ändern? – Richard

+0

Gibt es eine Möglichkeit, die Rechenraten auf dem Server zu berechnen? – RadleyMith

+0

Werfen Sie einen Blick auf http://stackoverflow.com/q/6864397/1048572, http://stackoverflow.com/q/714942/1048572. Und ja, Sie müssen alles, was von den Ergebnissen abhängt, ändern, um mit Async umzugehen. – Bergi

Antwort

5

Ich würde sagen, die Daten in N Reihen zu spleißen, bevor Sie in Verhältnisse berechnen. Machen Sie die Berechnungsverhältnisse zu einer einzigen Funktion, dh. Dieser Teil Ihres Programms // do some calculations... dann Promisify es mit Q.

Danach können Sie eine Reihe von Versprechen jedes Versprechen calculateRatiosForData(Nth row) erstellen.

Danach können Sie einen Anruf an Promise.all(yourArrayOfCalculateRatioPromises).

Das Problem hier ist, dass Sie immer noch alle diese Daten im Browser berechnen werden. Wenn möglich, wäre es besser, diese Verarbeitung auf den Server zu übertragen und eine POST Anfrage für das Computing zu verwenden. Die Versprechen Struktur wird immer noch gleich aussehen.

Es gibt auch die Frage, ob Sie diese berechnetenRatios für den Rest Ihres Skripts benötigen. Wenn Sie nicht gut, wenn Sie das tun, dann würden Sie nur den Rest des Skripts innerhalb der Promise.all(arrayOfPromises).then(function (result) { //rest of script} kapseln. Das Schlüsselstück dieses Codes ist die . Dann (Funktion() {}).

Ich würde vorschlagen, mit WebWorkers aber leider sind sie nicht von IE8 unterstützt. Es gibt Problemumgehungen in google code und here aber ich kann nicht dafür bürgen, wie gut diese Optionen funktionieren.

EDIT: Dies wird zeigen, wie das Versprechen zu machen

Es gibt grundsätzlich zwei Möglichkeiten, dies zu tun.

1) Sie können die calculateRatios Funktion im Stil eines hinteren Knoten schreiben und es dann promisify Q. mit

function calculateRatios (arrayInput, callback) { 
    //error checking if error 
    //callback(error) 

    //calculate the ratios algorithm then do 
    setTimeout(callback(undefined, data), 500); 
} 

Und dann promisify es würde wie folgt aussehen:

var Promise = require('q'), //however you want to do this in the browser 
    calculateRatiosAsync = Promise.promisify(calculateRatios); 

Ich persönlich mag diesen Weg, weil er mit anderen Control-Flow-Bibliotheken kompatibel ist, ohne die ursprüngliche Funktion ändern zu müssen, oder Sie können einfach die ursprüngliche Funktion so verwenden, wie Sie sie haben, wenn es nicht notwendig ist, sie zu promiden.

2) Der andere Weg ist explizit ein Versprechen zu erstellen.

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

HINWEIS: Es sollte beachtet werden, dass Sie das Versprechen Bibliothek anders erfordern müssen, aber ich überlasse das Ihnen.

+0

danke, könntest du vielleicht einen Beispielcode geben? – Richard

+0

Was willst du ein Beispiel von ... Ich brauche Kontext. Möchten Sie sehen, wie Sie ein Versprechen erstellen können? Möchten Sie sehen, wie Sie eine POST-Anfrage an den Server stellen und damit Versprechungen machen? Eine große Berechnung im Browser kann nicht wirklich eine große Berechnung im Browser sein, es sei denn, Sie machen den Algorithmus effizienter oder Sie laden ihn auf den Server. – RadleyMith

+0

Danke! Ich möchte einfach nur sehen, wie man "calculateRatiosForData" anpasst, so dass es 1000 Zeilen gleichzeitig berechnet, dann eine halbe Sekunde pausiert und erst dann wieder zurückkehrt, wenn es fertig ist. In einer Weise, die in IE8 funktioniert. Ich möchte definitiv nichts zum Server POST. Die große Berechnung im Browser funktioniert in allen modernen Browsern einwandfrei. – Richard

Verwandte Themen