Bootcamp i backendutveckling med Node.js · Lektion

Optimera Node.js-händelseslingan

Gå på djupet med händelseslingan för att identifiera blockerande operationer och optimera asynkron kod för bättre prestanda.

Lektion 3 av 411 steg

Optimera Node.js-händelseslingan är en gratis lektion i Bootcamp i backendutveckling med Node.js på CoddyKit. Detta är lektion 3 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Bootcamp i backendutveckling med Node.js, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Bootcamp i backendutveckling med Node.js innehåller totalt 4 lektioner.

Händelseloopen: Node.js hjärta

Välkommen! Node.js använder en modell med en enda tråd, men kan hantera många operationer samtidigt tack vare sin händelseloop. Den här loopen kontrollerar kontinuerligt om det finns uppgifter att köra.

Det är avgörande att optimera händelseloopen för Node.js-applikationer med hög prestanda. Det säkerställer att servern förblir responsiv och hanterar många användare effektivt.

Optimera Node.js-händelseslingan — illustration 1

Förstå blockerande operationer

En blockerande operation (eller synkron operation) är en operation som stoppar körningen av all annan JavaScript-kod tills den är klar. Föreställ er en ensam kassör som stannar för att räkna växel åt en kund medan en lång kö av andra kunder väntar.

I Node.js fryser en blockerande operation hela händelseloopen och hindrar den från att behandla andra inkommande förfrågningar eller uppgifter. Det leder till långsamma svarstider och en dålig användarupplevelse.

Identifiera kod som belastar processorn

Processorbundna uppgifter är operationer som använder mycket processortid. De väntar inte på externa resurser som databaser eller nätverksförfrågningar, utan utför helt enkelt omfattande beräkningar.

  • Komplexa beräkningar
  • Omfattande datatransformeringar
  • Synkrona loopar över mycket stora datamängder
  • Bildbehandling eller kryptografi

Det här är vanliga orsaker till att händelseloopen blockeras om de inte hanteras försiktigt.

Demo: En blockerande loop

Prova att köra det här exemplet. Lägg märke till hur meddelandet 'After blocking loop' fördröjs. Om detta vore en server skulle den inte svara på andra förfrågningar medan loopen körs.

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

Dela upp processorbundet arbete

För att förhindra blockering kan vi dela upp stora processorbundna uppgifter i mindre delar och skjuta upp körningen av dem. Då kan händelseloopen behandla andra uppgifter mellan delarna.

  • Använd setImmediate() för att schemalägga en funktion så att den körs efter den aktuella avsökningsfasen i händelseloopen.
  • Använd process.nextTick() för att schemalägga en funktion så att den körs före alla I/O-operationer i den aktuella fasen av händelseloopen.
  • Använd Worker Threads för verkligt omfattande beräkningar.

Demo: Skjut upp körningen med setImmediate

Här omstrukturerar vi den blockerande loopen med hjälp av setImmediate. Det gör att händelseloopen kan behandla återanropet från setTimeout mycket tidigare, även om allt arbete fortfarande utförs.

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 jämfört med setImmediate

Både process.nextTick() och setImmediate() skjuter upp körningen, men de fungerar i olika faser av händelseloopen:

  • process.nextTick(): Kör sitt återanrop *före* alla I/O-återanrop i den *aktuella* omgången av händelseloopen. Det används ofta för felhantering eller för att standardisera återanropsbeteende.
  • setImmediate(): Kör sitt återanrop i *check*-fasen, *efter* I/O-återanrop och före timers i *nästa* omgång av händelseloopen. Det är idealiskt för att dela upp långvariga uppgifter.

Bortom huvudtråden: Worker Threads

För verkligt processorintensiva operationer som inte enkelt kan delas upp i små delar erbjuder Node.js Worker Threads. Med dessa kan ni köra JavaScript-kod parallellt i helt separata trådar.

Worker Threads blockerar inte huvudloopen alls, vilket gör dem perfekta för tunga beräkningar som datakryptering, komplexa simuleringar eller behandling av stora filer.

Demo: En grundläggande Worker Thread

Så här kan en main.js-fil använda en worker för att lämna över tunga beräkningar. Huvudtråden förblir fri att utföra annat arbete.

Ni behöver även en worker.js-fil i samma katalog:

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

Kontrollera era kunskaper

Föreställ er en Node.js-webbserver. Vilken av följande operationer löper STÖRST risk att blockera händelseloopen och försämra serverns responsivitet?

Sammanfattning: Optimera händelseloopen

Bra jobbat! Ni har lärt er hur ni håller Node.js händelseloop igång smidigt för optimal prestanda:

  • Identifiera blockerande kod: Känn igen synkrona och processorintensiva uppgifter.
  • Dela upp arbetet: Använd setImmediate() eller process.nextTick() för att skjuta upp delar av långvariga uppgifter.
  • Använd Worker Threads: Lämna över tunga beräkningar till separata trådar för verklig parallellism.

Genom att förhindra att händelseloopen blockeras förblir era Node.js-applikationer responsiva och effektiva, även under hög belastning.

Gratis att börja

Lär dig JavaScript med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
22
Lektioner
92

Vanliga frågor

Är lektionen ”Optimera Node.js-händelseslingan” gratis?

Ja – hela texten till ”Optimera Node.js-händelseslingan” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Bootcamp i backendutveckling med Node.js, kan Ni uppgradera till CoddyKit PRO. Kursen i Bootcamp i backendutveckling med Node.js innehåller totalt 4 lektioner.

Vad lär jag mig i ”Optimera Node.js-händelseslingan”?

Gå på djupet med händelseslingan för att identifiera blockerande operationer och optimera asynkron kod för bättre prestanda. Ni övar på Bootcamp i backendutveckling med Node.js med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Bootcamp i backendutveckling med Node.js?

Du behöver inga förkunskaper. Utbildningen i Bootcamp i backendutveckling med Node.js på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 3 av 4.

Hur lång tid tar lektionen ”Optimera Node.js-händelseslingan”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Bootcamp i backendutveckling med Node.js-lektionen?

Ja. Varje Bootcamp i backendutveckling med Node.js-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Cachningsstrategier för Node.js
  2. Lastbalansera Node.js-appar
  3. Optimera Node.js-händelseslingan
  4. Profilering och identifiering av minnesläckor
← Tillbaka till Bootcamp i backendutveckling med Node.js