2017-05-26 4 views
2

Ich habe den folgenden Code:Versprechen basierte Funktion for-Schleife, die nicht laufen asynchron

function asyncLoop() { 
    return new Promise(function(res, rej) { 
     for(let i=0;i<=400000000;i++) { 
      if(i===400000000) {console.log("done"); res();} 
     } 
    }); 
} 

asyncLoop().then(()=>{console.log("then")}); 
console.log("out"); 

Ich erhalte die folgende Ausgabe:

done 
out 
then 

Nach meinem Verständnis von Versprechungen, die asyncLoop hätte asynchron laufen sollen und folgendes hätte sein sollen:

Was? Vermisse ich?

+0

https://stackoverflow.com/a/5436869/1278540 dann vs getan –

+1

@DebajyotiDas das ist über jQuery verspricht - das nutzt native. – Jamiec

+0

Versprechen haben keine "magischen" Eigenschaften, etwas asynchron zu machen, das nicht bereits asynchron ist. Sie sind lediglich ein standardisiertes Benachrichtigungs- und Fehlerbehandlungsschema - mehr nicht. Wenn die zugrundeliegende Operation nicht asynchron ist, wird sie NICHT durch ein Wrapping in eine Zusage irgendwie asynchron gemacht. – jfriend00

Antwort

3

Ihre Schleife ist in dem Rückruf, den Sie new Promise geben. Diese Funktion wird als ‚Vollstrecker‘ genannt:

function executor(resolve, reject) 

Der Testamentsvollstrecker ist synchron von new Promise genannt. Die Rolle des Executors besteht darin, irgendwelche asynchronen Ereignisse einzurichten, um resolve oder reject schließlich aufgerufen zu haben.

See MDN: Promise constructor parameters

Diese Funktion wird sofort als zwei Argumente mit den Auflösungsfunktionen aufgerufen.

Der Konstruktor wird nicht zurückkehren, bis der Testamentsvollstrecker

2

Sie haben eine falsche Annahme gemacht. Versprechen sind nicht asynchron, sie werden in einem asynchronen Kontext verwendet, um den Umgang mit Anrufen zu erleichtern. Um einen Prozess "asynchron" zu machen, könnten Sie setTimeout() verwenden.

function asyncLoop() { 
    return new Promise(function(res, rej) { 
     setTimeout(function() { 
      for(let i=0;i<=400000000;i++) { 
       if(i===400000000) {console.log("done"); res();} 
      } 
     }, 0); 
    }); 
} 

asyncLoop().then(()=>{console.log("then")}); 
console.log("out"); 
+1

JavaScript ist single-threaded und dies blockiert den Haupt-Browser-Thread genauso wie die ursprüngliche Frage, nur beim nächsten Lauf der Ereignisschleife. – jib

+0

In der Tat @jib, du hast recht. Es ist nicht wirklich asynchron, nur verzögert. – Booster2ooo

1

Ein Versprechen ist abgeschlossen hat nur ein Rückgabewert eine Rückruf legt stattdessen Rückrufe in eine Funktion, eine Konvention mit mehreren Vorteilen vorbei. Weitere Informationen finden Sie unter Using promises auf MDN.

JavaScript ist single-threaded mit einer Ereignisschleife. .then und setTimeout Ereignisse planen.

Alle JavaScript läuft auf dem Haupt-Thread des Browsers, wenn Sie ein worker erstellen:

function asyncLoop() { 
 
    for (let i = 0; i <= 400000000; i++) { 
 
    if (i == 400000000) { 
 
     self.postMessage('done'); 
 
    } 
 
    } 
 
} 
 

 
var blob = new Blob(["onmessage = " + asyncLoop.toString()], 
 
        {type: "text/javascript"}); 
 

 
var worker = new Worker(window.URL.createObjectURL(blob)); 
 

 
worker.onmessage = e => console.log(e.data); 
 
worker.postMessage("start");

+0

Danke für den Anteil an Web Workers! Das jetzt erforschen. – delfuego17

Verwandte Themen