2017-05-15 3 views
-1

Ich habe eine große und langsame synchrone Funktion, die ich es in einem Versprechen, es asynchron zu verwenden, umschließen möchte. Obwohl diese Funktion sekundäre Operationen enthält, ist es gut, sie auszuführen, ohne dass die Schnittstelle blockiert wird (Vermeidung der Wut des Benutzers: D).Call asynchrone Funktion in Aktion vuex

Was ich getan habe ist folgendes (commons.js, getrennte JavaScript-Datei):

exports default { 
    myHugeFunction: function(params) { 
    //lots...lots...lots..of synchronous things 
    } 
} 

Wo ich es nennen?

Vuejs Shop Modul

import commons from '/path/to/commons' 
export default { 
    actions: { 
    updateInterface: function() { 
    //overlay on 
    //some syncronous stuff... 
     Q.fcall(function() { 
     commons.myHugeFunction(params); 
     } 
    //some others syncronous stuff... 
    //overlay off 
    } 
    } 
} 

Trotzdem scheint es gut zu funktionieren, aber ich habe das gesamte Frontend stecken, da die große Funktion beendet hat. Ich benutze, um ein Overlay vor der Ausführung und danach, aber ich kann es nicht sehen, wenn es in der dom ist (aber das ist wahrscheinlich ein anderes Problem außerhalb des Umfangs ...).

Ich stelle mir vor, es ist Ausführung wie etwas, das von einem separaten Thread behandelt werden könnte, so dass der Benutzer während dieser Zeit andere Sachen tun kann.

Ist weil "vielleicht" die Anwendung vollständig im Frontend (Browser)?

+0

egal, wo Sie es hinstellen, wenn Sie eine riesige synchrone Funktion haben, Block ks io, es wird Io blockieren. fixiere die Funktion selbst. –

+0

Vielen Dank für die nützliche Antwort! Jetzt ist das Problem klar. Das ist gemeinsamer Code mit einem anderen Team, das sehr stolz auf seine Arbeit ist: D und kann nicht aus irgendeinem Grund (dieser Code) berühren, so dass wir das Problem umgehen müssen, kann auch möglich sein? JA oder NEIN könnte auch eine gute Antwort sein, nur um zu wissen, wie wir uns jetzt bewegen können :) – grimi

Antwort

0

Sie könnten einen Web-Arbeiter dafür verwenden, unter der Bedingung, dass myHugeFunction keine globalen Variablen verwendet, die nur im window Kontext verfügbar sind. Zum Beispiel kann es nicht mit dem DOM interagieren. Sie müssen alle externen Abhängigkeiten als Parameter übergeben oder die Abhängigkeiten im Web-Worker-Kontext einschließen.

Hier ist, wie es aussehen würde:

Verschieben myHugeFunction aus commons.js in eine neue, separate worker.js Datei, die Sie sollten nicht import. Ihre worker.js Datei sollte wie folgt aussehen:

function myHugeFunction(...params) { 
    //lots...lots...lots..of synchronous things 
    console.log('parameters', params); 
    return 'myHugeFunction return value'; 
} 

onmessage = function(e) { 
    postMessage(myHugeFunction(...e.data)); 
} 

In Ihrem commons.js Sie diese Hilfsfunktion promiseWork definieren könnte:

exports default { 
    promiseWork: function(script, params) { 
     return new Promise(function (resolve, reject) { 
      var worker = new Worker(script); 
      worker.onmessage = function(e) { 
       resolve(e.data); 
      } 
      worker.onerror = function(e) { 
       reject('[' + e.filename + ':' + e.lineno + '] ' + e.message); 
      } 
      worker.postMessage(params); 
     }); 
    } 
} 

In Ihrem Vuejs Speicher-Modul Sie promiseWork mit dem Skriptnamen nennen würde und Parameter (ein Array) als Argumente:

export default { 
    actions: { 
     updateInterface: function() { 
      //overlay on 
      //some synchronous stuff... 
      promiseWork('worker.js', params).then(function() { 
       console.log('huge work completed asynchronously'); 
       //some other stuff... 
       //overlay off 
      }); 
     } 
    } 
}