Gemäß der Ereignisschleife node.js Legendes , node.js unterstützt ein einzelnes Thread - Modell. Das heißt, wenn ich mehrere Anforderungen an einen node.js-Server stelle, wird nicht für jede Anforderung ein neuer Thread erzeugt, sondern jede Anforderung einzeln ausgeführt. Wenn ich für die erste Anforderung in meinem node.js-Code Folgendes tue und währenddessen eine neue Anforderung auf dem Knoten eingeht, muss die zweite Anforderung warten, bis die erste Anforderung abgeschlossen ist, einschließlich einer Ruhezeit von 5 Sekunden. Richtig?
var sleep = require('sleep');
sleep.sleep(5)//sleep for 5 seconds
Gibt es eine Möglichkeit, wie node.js für jede Anforderung einen neuen Thread erzeugen kann, damit die zweite Anforderung nicht auf den Abschluss der ersten Anforderung warten muss, oder kann ich den Ruhezustand nur für einen bestimmten Thread aufrufen?
quelle
Antworten:
Wenn Sie sich auf den Ruhezustand des npm-Moduls beziehen , wird in der Readme-Datei darauf hingewiesen, dass
sleep
die Ausführung blockiert wird. Sie haben also Recht - es ist nicht das, was Sie wollen. Stattdessen möchten Sie setTimeout verwenden, das nicht blockiert. Hier ist ein Beispiel:setTimeout(function() { console.log('hello world!'); }, 5000);
Für alle, die dies mit es7 async / await tun möchten, sollte dieses Beispiel helfen:
const snooze = ms => new Promise(resolve => setTimeout(resolve, ms)); const example = async () => { console.log('About to snooze without halting the event loop...'); await snooze(1000); console.log('done!'); }; example();
quelle
setTimeout
, speichert es das Ereignis in der Warteschlange und kann dann mit der Ausführung der nächsten Anforderung beginnen. Nach fünf Sekunden wird das Ereignis aus der Warteschlange entfernt und der Rückruf ausgeführt (dieconsole.log
in diesem Fall enthaltene Funktion ).Wenn Sie eine Schleife mit einer asynchronen Anforderung in jeder haben und zwischen jeder Anforderung eine bestimmte Zeit möchten, können Sie diesen Code verwenden:
var startTimeout = function(timeout, i){ setTimeout(function() { myAsyncFunc(i).then(function(data){ console.log(data); }) }, timeout); } var myFunc = function(){ timeout = 0; i = 0; while(i < 10){ // By calling a function, the i-value is going to be 1.. 10 and not always 10 startTimeout(timeout, i); // Increase timeout by 1 sec after each call timeout += 1000; i++; } }
In diesem Beispiel wird nach jeder Anforderung 1 Sekunde gewartet, bevor die nächste gesendet wird.
quelle
myAsyncFunc
in Ihrem Fall.Bitte beachten Sie das Deasync- Modul. Ich persönlich mag die Promise-Methode nicht, um alle Funktionen asynchron zu machen, und das Schlüsselwort async / warte auf irgendetwas. Und ich denke, die offizielle node.js sollte in Betracht ziehen, die Event-Loop-API verfügbar zu machen, dies wird die Callback-Hölle einfach lösen. Node.js ist ein Framework, keine Sprache.
var node = require("deasync"); node.loop = node.runLoopOnce; var done = 0; // async call here db.query("select * from ticket", (error, results, fields)=>{ done = 1; }); while (!done) node.loop(); // Now, here you go
quelle
Bei der Arbeit mit asynchronen Funktionen oder Observablen, die von Bibliotheken von Drittanbietern bereitgestellt werden, z. B. Cloud Firestore, habe ich festgestellt, dass Funktionen der
waitFor
unten gezeigten Methode (TypeScript, aber Sie haben die Idee ...) hilfreich sind, wenn Sie auf einen Prozess warten müssen zu vervollständigen, aber Sie möchten keine Rückrufe in Rückrufe in Rückrufe einbetten müssen oder eine Endlosschleife riskieren.Diese Methode ähnelt einer
while (!condition)
Schlafschleife, liefert jedoch asynchron und führt in regelmäßigen Abständen einen Test der Abschlussbedingung durch, bis true oder timeout ausgeführt wird.export const sleep = (ms: number) => { return new Promise(resolve => setTimeout(resolve, ms)) } /** * Wait until the condition tested in a function returns true, or until * a timeout is exceeded. * @param interval The frenequency with which the boolean function contained in condition is called. * @param timeout The maximum time to allow for booleanFunction to return true * @param booleanFunction: A completion function to evaluate after each interval. waitFor will return true as soon as the completion function returns true. */ export const waitFor = async function (interval: number, timeout: number, booleanFunction: Function): Promise<boolean> { let elapsed = 1; if (booleanFunction()) return true; while (elapsed < timeout) { elapsed += interval; await sleep(interval); if (booleanFunction()) { return true; } } return false; }
Angenommen, Sie haben einen lang laufenden Prozess in Ihrem Backend, den Sie abschließen möchten, bevor eine andere Aufgabe ausgeführt wird. Wenn Sie beispielsweise eine Funktion haben, die eine Liste von Konten zusammenfasst, die Konten jedoch vor der Berechnung aus dem Backend aktualisieren möchten, können Sie Folgendes tun:
async recalcAccountTotals() : number { this.accountService.refresh(); //start the async process. if (this.accounts.dirty) { let updateResult = await waitFor(100,2000,()=> {return !(this.accounts.dirty)}) } if(!updateResult) { console.error("Account refresh timed out, recalc aborted"); return NaN; } return ... //calculate the account total. }
quelle