Bootcamp i backendudvikling med Node.js · Lektion

Optimering af Node.js' event loop

Gå i dybden med event loop for at identificere blokerende operationer og optimere asynkron kode for bedre ydeevne.

Lektion 3 af 411 trin

Optimering af Node.js' event loop er en gratis Bootcamp i backendudvikling med Node.js-lektion på CoddyKit. Dette er lektion 3 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i Bootcamp i backendudvikling med Node.js, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Bootcamp i backendudvikling med Node.js-kurset indeholder 4 lektioner i alt.

Event Loop: Hjertet i Node.js

Velkommen! Node.js bruger en model med én tråd, men håndterer mange handlinger samtidigt takket være sin Event Loop. Denne løkke tjekker kontinuerligt, om der er opgaver, der skal udføres.

Optimering af event loop er afgørende for Node.js-applikationer med høj ydeevne. Det sikrer, at din server forbliver responsiv og håndterer mange brugere effektivt.

Optimering af Node.js' event loop — illustration 1

Forstå blokerende handlinger

En blokerende handling (eller synkron handling) er en handling, der standser udførelsen af al anden JavaScript-kode, indtil den er færdig. Forestil dig en enkelt kassemedarbejder, der stopper for at tælle byttepenge til én kunde, mens en lang kø af andre kunder venter.

I Node.js fastfryser en blokerende handling hele event loop og forhindrer den i at behandle andre indgående forespørgsler eller opgaver. Det fører til lange svartider og en dårlig brugeroplevelse.

Find kode, der overbelaster CPU'en

CPU-bundne opgaver er handlinger, der bruger meget processortid. De venter ikke på eksterne ressourcer som databaser eller netværksforespørgsler; de udfører beregninger.

  • Komplekse beregninger
  • Tunge datatransformationer
  • Synkrone løkker over meget store datasæt
  • Billedbehandling eller kryptografi

Det er almindelige årsager til, at event loop bliver blokeret, hvis de ikke håndteres omhyggeligt.

Demo: En blokerende løkke

Prøv at køre dette eksempel. Bemærk, hvordan meddelelsen 'After blocking loop' bliver forsinket, og hvis dette var en server, ville den ikke svare på andre forespørgsler, mens løkken blev udført.

console.log("Before blocking loop.");

const startTime = Date.now();
// Simulate a CPU-intensive task
for (let i = 0; i < 5000000000; i++) {
  // Do nothing, just loop
}
const endTime = Date.now();

console.log(`Blocking loop finished in ${endTime - startTime}ms.`);
console.log("After blocking loop.");

// This will be delayed because the loop blocked the event loop
setTimeout(() => {
  console.log("This message is from setTimeout (delayed).");
}, 0);

Opdel CPU-bundet arbejde

For at forhindre blokering kan vi opdele store CPU-bundne opgaver i mindre dele og udskyde deres udførelse. Det giver event loop mulighed for at behandle andre opgaver mellem delene.

  • Brug setImmediate() til at planlægge en funktion, så den kører efter den aktuelle poll-fase i event loop.
  • Brug process.nextTick() til at planlægge en funktion, så den kører før alle I/O-handlinger i den aktuelle fase af event loop.
  • Brug Worker Threads til virkelig tunge beregninger.

Demo: Udskydelse med setImmediate

Her omstrukturerer vi den blokerende løkke ved hjælp af setImmediate. Det giver event loop mulighed for at behandle setTimeout-callbacken langt tidligere, selvom det samlede arbejde stadig udføres.

console.log("Before deferred loop.");

let count = 0;
const maxCount = 5000000000;

function doWorkChunk() {
  const chunkSize = 10000000; // Process 10 million iterations at a time
  const start = count;
  const end = Math.min(count + chunkSize, maxCount);

  for (let i = start; i < end; i++) {
    // Simulate work
  }

  count = end;

  if (count < maxCount) {
    setImmediate(doWorkChunk); // Schedule next chunk immediately
  } else {
    console.log("Deferred loop finished.");
  }
}

const startTime = Date.now();
setImmediate(doWorkChunk); // Start the deferred work

console.log("After initiating deferred loop.");

// This setTimeout will run much sooner now
setTimeout(() => {
  console.log("This message is from setTimeout (not delayed).");
  const endTime = Date.now();
  console.log(`Total time (approx) for deferred loop: ${endTime - startTime}ms.`);
}, 0);

process.nextTick sammenlignet med setImmediate

Både process.nextTick() og setImmediate() udskyder udførelsen, men de arbejder i forskellige faser af event loop:

  • process.nextTick(): Kører sin callback *før* alle I/O-callbacks i den *aktuelle* omgang af event loop. Den bruges ofte til fejlhåndtering eller til at ensrette callback-adfærd.
  • setImmediate(): Kører sin callback i *check*-fasen, *efter* I/O-callbacks og før timere i den *næste* omgang af event loop. Den er velegnet til at opdele langvarige opgaver.

Ud over hovedtråden: Worker Threads

Til virkelig CPU-intensive handlinger, som ikke nemt kan opdeles i små dele, tilbyder Node.js Worker Threads. De giver dig mulighed for at køre JavaScript-kode parallelt i helt separate tråde.

Worker Threads blokerer slet ikke den primære event loop, hvilket gør dem perfekte til tunge beregninger som datakryptering, komplekse simuleringer eller behandling af store filer.

Demo: Grundlæggende Worker Thread

Her kan du se, hvordan en main.js-fil kan bruge en worker til at overlade tunge beregninger. Hovedtråden forbliver fri til at udføre andet arbejde.

Du skal også have en worker.js-fil i samme mappe:

const { parentPort } = require('worker_threads'); parentPort.on('message', (task) => { console.log('Worker received task:', task); let result = 0; for (let i = 0; i < task; i++) { result += i; // Simulate heavy computation } parentPort.postMessage(result); });
const { Worker } = require('worker_threads');

console.log("Main thread started.");

// Create a new worker thread (requires 'worker.js' file)
const worker = new Worker('./worker.js');

// Listen for messages from the worker
worker.on('message', (msg) => {
  console.log(`Worker finished: Result = ${msg}`);
});

// Listen for errors from the worker
worker.on('error', (err) => {
  console.error(`Worker error: ${err}`);
});

// Listen for worker exit
worker.on('exit', (code) => {
  if (code !== 0)
    console.error(`Worker stopped with exit code ${code}`);
});

// Send a heavy task to the worker
worker.postMessage(500000000); // Send a large number for heavy computation

console.log("Main thread sent task to worker.");
console.log("Main thread continues non-blocking work.");

// Simulate other work in the main thread
let mainThreadCounter = 0;
const intervalId = setInterval(() => {
  console.log(`Main thread doing other work: ${mainThreadCounter++}`);
  if (mainThreadCounter >= 5) {
    clearInterval(intervalId);
  }
}, 100);

Tjek din forståelse

Forestil dig en Node.js-webserver. Hvilken af følgende handlinger vil med STØRST sandsynlighed blokere event loop og påvirke serverens reaktionsevne negativt?

Opsummering: Optimering af event loop

Godt gået! Du har lært, hvordan du holder Node.js' event loop kørende uden problemer for at opnå optimal ydeevne:

  • Find blokerende kode: Genkend synkrone, CPU-intensive opgaver.
  • Opdel arbejdet: Brug setImmediate() eller process.nextTick() til at udskyde dele af lange opgaver.
  • Udnyt Worker Threads: Overlad tunge beregninger til separate tråde for at opnå ægte parallelisme.

Ved at forhindre blokering af event loop forbliver dine Node.js-applikationer responsive og effektive, selv under stor belastning.

Gratis at komme i gang

Lær JavaScript med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
22
Lektioner
92

Ofte stillede spørgsmål

Er lektionen “Optimering af Node.js' event loop” gratis?

Ja — hele teksten til “Optimering af Node.js' event loop” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af Bootcamp i backendudvikling med Node.js-kurset, skal du opgradere til CoddyKit PRO. Bootcamp i backendudvikling med Node.js-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Optimering af Node.js' event loop”?

Gå i dybden med event loop for at identificere blokerende operationer og optimere asynkron kode for bedre ydeevne. Du øver dig i Bootcamp i backendudvikling med Node.js med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Bootcamp i backendudvikling med Node.js?

Der kræves ingen tidligere erfaring. Bootcamp i backendudvikling med Node.js på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 3 af 4.

Hvor lang tid tager lektionen “Optimering af Node.js' event loop”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Bootcamp i backendudvikling med Node.js-lektion?

Ja. Alle Bootcamp i backendudvikling med Node.js-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Cachingstrategier til Node.js
  2. Load balancing af jeres Node.js-apps
  3. Optimering af Node.js' event loop
  4. Profilering og registrering af memory leaks
← Tilbage til Bootcamp i backendudvikling med Node.js