Bootcamp i backendutvikling med Node.js · leksjon

Optimalisere Node.js-hendelsesløkken

Gå i dybden på hendelsesløkken for å identifisere blokkerende operasjoner og optimalisere asynkron kode for bedre ytelse.

Leksjon 3 av 411 trinn

Optimalisere Node.js-hendelsesløkken er en gratis leksjon i Bootcamp i backendutvikling med Node.js på CoddyKit. Dette er leksjon 3 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Bootcamp i backendutvikling med Node.js, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Bootcamp i backendutvikling med Node.js inneholder totalt 4 leksjoner.

Hendelsesløkken: Hjertet i Node.js

Velkommen! Node.js bruker en entrådet modell, men håndterer mange operasjoner samtidig takket være hendelsesløkken. Denne løkken sjekker kontinuerlig etter oppgaver som skal utføres.

Optimalisering av hendelsesløkken er avgjørende for Node.js-applikasjoner med høy ytelse. Den sørger for at serveren forblir responsiv og håndterer mange brukere effektivt.

Optimalisere Node.js-hendelsesløkken — illustrasjon 1

Forstå blokkerende operasjoner

En blokkerende operasjon (eller synkron operasjon) er en operasjon som stanser kjøringen av all annen JavaScript-kode til den er fullført. Se for deg en enslig kassabetjent som stopper for å telle opp veksel til én kunde, mens en lang kø med andre kunder venter.

I Node.js fryser en blokkerende operasjon hele hendelsesløkken og hindrer den i å behandle andre innkommende forespørsler eller oppgaver. Dette fører til lange svartider og en dårlig brukeropplevelse.

Oppdage kode som overbelaster prosessoren

Prosessorbundne oppgaver er operasjoner som bruker mye prosessortid. De venter ikke på eksterne ressurser som databaser eller nettverksforespørsler; de utfører bare omfattende beregninger.

  • Komplekse beregninger
  • Omfattende datatransformasjoner
  • Synkrone løkker over svært store datasett
  • bildebehandling eller kryptografi

Dette er vanlige årsaker til at hendelsesløkken blokkeres hvis de ikke håndteres forsiktig.

Demo: En blokkerende løkke

Prøv å kjøre dette eksempelet. Legg merke til hvordan meldingen «After blocking loop» blir forsinket. Hvis dette hadde vært en server, ville den ikke svart på andre forespørsler mens løkken kjørte.

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

Bryte ned prosessorbundet arbeid

For å unngå blokkering kan vi dele store prosessorbundne oppgaver opp i mindre deler og utsette kjøringen av dem. Da kan hendelsesløkken behandle andre oppgaver mellom delene.

  • Bruk setImmediate() til å planlegge en funksjon som skal kjøres etter den gjeldende poll-fasen i hendelsesløkken.
  • Bruk process.nextTick() til å planlegge en funksjon som skal kjøres før alle I/O-operasjoner i den gjeldende fasen av hendelsesløkken.
  • For virkelig tunge beregninger kan du bruke Worker Threads.

Demo: Utsette med setImmediate

Her refaktorerer vi den blokkerende løkken ved hjelp av setImmediate. Dette lar hendelsesløkken behandle setTimeout-tilbakekallet mye tidligere, selv om alt arbeidet fortsatt blir utført.

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 kontra setImmediate

Både process.nextTick() og setImmediate() utsetter kjøringen, men de opererer i forskjellige faser av hendelsesløkken:

  • process.nextTick(): Kjører tilbakekallet *før* alle I/O-tilbakekall i den *gjeldende* runden av hendelsesløkken. Det brukes ofte til feilhåndtering eller for å standardisere oppførselen til tilbakekall.
  • setImmediate(): Kjører tilbakekallet i *check*-fasen, *etter* I/O-tilbakekall og før tidsstyrere i den *neste* runden av hendelsesløkken. Det egner seg godt til å dele opp langvarige oppgaver.

Utover hovedtråden: Worker Threads

For virkelig prosessorintensive operasjoner som ikke enkelt kan deles opp i små deler, tilbyr Node.js Worker Threads. Disse lar deg kjøre JavaScript-kode parallelt i helt separate tråder.

Worker Threads blokkerer ikke hovedtråden for hendelsesløkken i det hele tatt, og egner seg derfor perfekt til tunge beregninger som datakryptering, komplekse simuleringer eller behandling av store filer.

Demo: Grunnleggende Worker Thread

Slik kan en main.js-fil bruke en worker til å avlaste tunge beregninger. Hovedtråden er fortsatt ledig til å utføre annet arbeid.

Du trenger også en worker.js-fil i samme 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);

Test forståelsen din

Se for deg en Node.js-nettserver. Hvilken av følgende operasjoner vil SANNsynligvis blokkere hendelsesløkken og påvirke serverens responsivitet negativt?

Oppsummering: Optimalisering av hendelsesløkken

Godt jobbet! De har lært hvordan de kan holde Node.js-hendelsesløkken i jevn drift for optimal ytelse:

  • Identifiser blokkerende kode: Gjenkjenn synkrone, prosessorintensive oppgaver.
  • Del opp arbeidet: Bruk setImmediate() eller process.nextTick() til å utsette deler av lange oppgaver.
  • Utnytt Worker Threads: Avlast tunge beregninger til separate tråder for ekte parallellitet.

Ved å hindre at hendelsesløkken blokkeres, forblir Node.js-applikasjonene deres responsive og effektive, selv under høy belastning.

Gratis å komme i gang

Lær deg JavaScript med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
22
Leksjoner
92

Ofte stilte spørsmål

Er leksjonen «Optimalisere Node.js-hendelsesløkken» gratis?

Ja – hele teksten i «Optimalisere Node.js-hendelsesløkken» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av Bootcamp i backendutvikling med Node.js-kurset, kan du oppgradere til CoddyKit PRO. Kurset i Bootcamp i backendutvikling med Node.js inneholder totalt 4 leksjoner.

Hva lærer jeg i «Optimalisere Node.js-hendelsesløkken»?

Gå i dybden på hendelsesløkken for å identifisere blokkerende operasjoner og optimalisere asynkron kode for bedre ytelse. Du øver på Bootcamp i backendutvikling med Node.js med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med Bootcamp i backendutvikling med Node.js?

Ingen tidligere erfaring er nødvendig. Bootcamp i backendutvikling med Node.js på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 3 av 4.

Hvor lang tid tar leksjonen «Optimalisere Node.js-hendelsesløkken»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne Bootcamp i backendutvikling med Node.js-leksjonen?

Ja. Alle Bootcamp i backendutvikling med Node.js-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Bufringsstrategier for Node.js
  2. Lastbalansering av Node.js-apper
  3. Optimalisere Node.js-hendelsesløkken
  4. Profilering og oppdaging av minnelekkasjer
← Tilbake til Bootcamp i backendutvikling med Node.js