Vodič za obećanje Node.js

⚡ Pametni sažetak

Obećanja u Node.js-u zamjenjuju duboko ugniježđene povratne funkcije vraćenim objektom koji se izvršava jednom, pa se asinhroni rad s bazom podataka čita kao ravni lanac then klauzula umjesto piramide anonimnih funkcija.

  • 🔘 Problem s povratnim pozivom: Ugniježđeni povratni pozivi postaju dugi i teški za održavanje.
  • ☑️ Osnove obećanja: Obećanje vraća vrijednost i izvršava se točno jednom.
  • ✅ Lanac: zatim sam vraća obećanje, pa se umetci izvršavaju redom.
  • 🧪 Prilagođena obećanja: Denodeify u q biblioteci omotava svaki povratni poziv.
  • 🛠️ Moderni oblik: async i await konzumiraju obećanja bez povratnih poziva then.
  • 📊 Pravilo pogreške: Neobrađena odbijanja prekidaju Node.js od verzije 15.

Node.js Promise tutorial koji prikazuje povratne pozive povezane u obećanja

U prethodnim vodičima vidjeli ste funkcije povratnog poziva koje se koriste za asinkrone događaje. Ali ponekad funkcije povratnog poziva mogu postati noćna mora kada se počnu ugniježđivati, a program postane dug i složen.

Što su obećanja?

Prije nego što počnemo s obećanjima, prvo ćemo se ponovno osvrnuti na to što su "callback" funkcije u Node.jsOve povratne funkcije smo već puno puta vidjeli u prethodnim poglavljima, pa ćemo brzo proći kroz jednu od njih.

Primjer u nastavku prikazuje isječak koda koji se koristi za povezivanje s a MongoDB bazu podataka i izvršite operaciju ažuriranja jednog od zapisa u bazi podataka.

Node.js funkcija povratnog poziva koja se povezuje s MongoDB i ažuriranje zapisa

  1. U gornjem kodu, dio funkcije (err,db) poznat je kao deklaracija anonimne funkcije ili funkcije povratnog poziva. Kada MongoClient stvori vezu s MongoDB baze podataka, vratit će se na funkciju povratnog poziva nakon završetka operacije povezivanja. Dakle, u određenom smislu, operacije povezivanja odvijaju se u pozadini, a kada su gotove, pozivaju našu funkciju povratnog poziva. Imajte na umu da je ovo jedna od ključnih točaka Node.js-a koja omogućuje istovremeno odvijanje mnogih operacija i na taj način ne blokira nijednog korisnika u izvođenju operacije.
  2. Drugi blok koda je ono što se izvršava kada se stvarno pozove funkcija povratnog poziva. Funkcija povratnog poziva samo ažurira jedan zapis u našem MongoDB baza podataka.

Pa što je onda obećanje? Pa, obećanje je samo poboljšanje funkcija povratnog poziva u Node.js. Tijekom životnog ciklusa razvoja može doći do slučaja kada biste trebali ugniježditi više funkcija povratnog poziva zajedno. To može postati neuredno i teško ga je održavati u određenom trenutku. Ukratko, obećanje je poboljšanje povratnih poziva koje teži ublažavanju ovih problema.

Osnovna sintaksa obećanja prikazana je u nastavku;

var promise = doSomethingAync()
promise.then(onFulfilled, onRejected)
  • "doSomethingAync" je bilo koji povratni poziv ili asinkrona funkcija koja obavlja neku vrstu obrade.
  • Ovaj put, kada se definira povratni poziv, postoji vrijednost koja se vraća pod nazivom "obećanje".
  • Kada se obećanje vrati, ono može imati 2 izlaza. To je definirano klauzulom 'then'. Ili operacija može biti uspješna što je označeno parametrom 'onFulfilled'. Ili može imati pogrešku koja je označena parametrom 'onRejected'.

A obećanje nalazi se u jednoj od tri države i nastani se jednom:

Država Značenje
U tijeku Posao nije završen.
ispunjena onFulfilled se izvršava s vrijednošću.
Odbijen onRejected se izvršava s greškom.

Bilješka: Dakle, ključni aspekt obećanja je povratna vrijednost. Ne postoji koncept povratne vrijednosti kada se radi s normalnim povratnim pozivima u Node.js. Zbog povratne vrijednosti imamo veću kontrolu nad načinom na koji se funkcija povratnog poziva može definirati.

Napomena o verziji: Ovi primjeri još uvijek rade na Node.js 24, Active LTS liniji u 2026. Od Node.js 15 neobrađeno odbijanje završava proces umjesto ispisa upozorenja, stoga zatvorite svaki lanac s .catch().

U sljedećoj temi vidjet ćemo primjer obećanja i kakvu korist imaju od povratnih poziva.

Povratni pozivi na obećanja

Sada pogledajmo primjer kako možemo koristiti “obećanja” unutar Node.js aplikacije. Kako biste koristili obećanja u aplikaciji Node.js, prvo morate preuzeti i instalirati modul 'promise'.

Zatim ćemo izmijeniti naš kod kao što je prikazano u nastavku, koji ažurira EmployeeName u kolekciji 'Employee' korištenjem obećanja.

Korak 1) Instaliranje NPM moduli

Za korištenje Promises unutar Node.js aplikacije, potreban je promises modul. Za instalaciju promises modula, pokrenite sljedeću naredbu.

obećanje instalacije npm-a

Korak 2) Izmijenite kod da uključi obećanja

Snimka zaslona urednika modula obećanja koji prepisuje MongoDB ažuriranje

var Promise = require('promise');
var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost/EmployeeDB';

MongoClient.connect(url)
    .then(function(err, db) {
        db.collection('Employee').updateOne({
            "EmployeeName": "Martin"
        }, {
            $set: {
                "EmployeeName": "Mohan"
            }
        });
    }); 

Code Objašnjenje:

  1. Prvi dio je uključivanje modula 'promise' koji će nam omogućiti korištenje funkcionalnosti obećanja u našem kodu.
  2. Sada možemo dodati funkciju 'then' našoj funkciji MongoClient.connect. Ono što ovo čini je da kada se uspostavi veza s bazom podataka, moramo izvršiti isječak koda definiran nakon toga.
  3. Naposljetku, definiramo naš isječak koda koji obavlja posao ažuriranja EmployeeName zaposlenika s imenom "Martin" u "Mohan".

Bilješka:

Ako sada provjerite sadržaj svog MongoDB baze podataka, otkrit ćete da ako postoji zapis s EmployeeName "Martin", on će se ažurirati na "Mohan".

Kako biste provjerili jesu li podaci pravilno umetnuti u bazu podataka, morate izvršiti sljedeće naredbe MongoDB

  1. koristite EmployeeBay
  2. db.Employee.find({ImeZaposlenika: “Mohan”})

Prva naredba osigurava da ste povezani s bazom podataka EmployeeDB. Druga naredba traži zapis koji sadrži ime zaposlenika „Mohan“.

Suočavanje s ugniježđenim obećanjima

Prilikom definiranja obećanja, potrebno je napomenuti da metoda “then” sama vraća obećanje. Dakle, u određenom smislu obećanja mogu biti ugniježđena ili lančano povezana jedno s drugim.

U donjem primjeru koristimo ulančavanje za definiranje 2 funkcije povratnog poziva, od kojih obje umeću zapis u MongoDB baza podataka.

(bilješke: Ulančavanje je koncept koji se koristi za međusobno povezivanje izvršenja metoda. Pretpostavimo da vaša aplikacija ima 2 metode pod nazivom 'methodA' i 'methodB'. A logika je bila takva da se 'methodB' treba pozvati nakon 'methodA', tada biste ulančali izvršenje na takav način da se 'methodB' poziva izravno nakon 'methodA.')

Ključna stvar koju treba primijetiti u ovom primjeru je da kod postaje čišći, čitljiv i održavan korištenjem ugniježđenih obećanja.

Lančane then klauzule umetanjem dvaju zapisa zaposlenika u MongoDB

var Promise = require('promise');
var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost/EmployeeDB';
MongoClient.connect(url)

.then(function(db) {
    db.collection('Employee').insertOne({
        Employeeid: 4,
        EmployeeName: "NewEmployee"
    })

    .then(function(db1) {
        db1.collection('Employee').insertOne({
            Employeeid: 5,
            EmployeeName: "NewEmployee1"
        })
    })
});

Code Objašnjenje:

  1. Sada definiramo 2 "then" klauzule koje se izvršavaju jedna za drugom. U prvoj then klauzuli, mi prosljeđujemo 'db' parametar koji sadrži našu vezu s bazom podataka. Zatim koristimo svojstvo zbirke 'db' veze za umetanje zapisa u kolekciju 'Zaposlenik'. Metoda 'insertOne' koristi se za umetanje stvarnog dokumenta u zbirku zaposlenika.
  2. Zatim koristimo 2nd zatim klauzula također za umetanje drugog zapisa u bazu podataka.

Ako sada provjerite sadržaj svog MongoDB u bazu podataka pronaći ćete 2 zapisa umetnuta u MongoDB baza podataka.

Moderni ekvivalent: async i await, standardni od ES2017, konzumiraju ova obećanja bez povratnih poziva i uglavnom su zamijenili na bazi generatora biblioteke za kontrolu protoka kao što je co, dok izvorna podrška za Promise čini q i bluebird suvišnima. Drugi blok pokazuje da se tada prima samo db.

Stvaranje prilagođenog obećanja

Prilagođeno obećanje može se kreirati korištenjem Node.js modula pod nazivom 'q'. Biblioteku 'q' potrebno je preuzeti i instalirati pomoću Node Package Managera. Nakon korištenja biblioteke 'q', može se pozvati metoda "denodeify" koja će uzrokovati da bilo koja funkcija postane funkcija koja vraća obećanje.

U donjem primjeru izradit ćemo jednostavnu funkciju pod nazivom "Dodaj" koja će zbrojiti 2 broja. Pretvorit ćemo ovu funkciju u funkciju za vraćanje obećanja.

Kada to učinimo, upotrijebit ćemo obećanje koje je vratila funkcija Dodaj za prikaz poruke u console.log.

Slijedimo korake u nastavku za stvaranje prilagođene funkcije za vraćanje obećanja.

Korak 1) Instaliranje NPM modula

Za korištenje 'q' unutar Node.js aplikacije, potreban je modul 'q'. Za instalaciju modula 'q', pokrenite sljedeću naredbu

npm instaliraj q

Korak 2) Definirajte sljedeći kod koji će se koristiti za stvaranje prilagođenog obećanja.

Prilagođeno obećanje izrađeno od strane wrapaping funkcija zbrajanja s q denodifikacijom

Code Objašnjenje:

  1. Prvi bit je uključivanje biblioteke 'q' pomoću ključne riječi require. Korištenjem ove biblioteke moći ćemo definirati bilo koju funkciju za povratni poziv.
  2. Stvaramo funkciju koja se zove Add koja će zbrajati 2 broja definirana u varijablama a i b. Zbroj ovih vrijednosti bit će pohranjen u varijabli c.
  3. Zatim koristimo q biblioteku za denodifikaciju (metoda koja se koristi za pretvaranje bilo koje funkcije u funkciju koja vraća obećanje) naše Add funkcije ili drugim riječima, pretvaramo našu Add funkciju u funkciju koja vraća obećanje.
  4. Sada pozivamo našu funkciju "Dodaj" i možemo dobiti povratnu obećanu vrijednost zbog prethodnog koraka koji smo izveli denodeificiranja funkcije Dodaj.
  5. Ključna riječ 'then' koristi se za određivanje da će se, ako se funkcija uspješno izvrši, u console.logu prikazati niz znakova „Funkcija dodavanja je završena“.

Kada se gornji kod pokrene, izlaz "Funkcija zbrajanja dovršena" bit će prikazan u console.log kao što je prikazano u nastavku.

Ispis izlaza konzole Funkcija dodavanja završena iz prilagođenog obećanja

Pitanja i odgovori

Od Node.js 15 proces završava s kodom koji nije nula, a ne s upozorenjem. Priložite .catch() svakom lancu ili registrirajte rukovatelj procesom za prijavu i oporavak.

.catch() prima bilo koju grešku bačenu ranije u lancu, poput try bloka. .finally() se izvršava bez obzira na to kako se lanac završio, pa je prikladan za zatvaranje veze.

Promise.all brzo ne uspije ako se jedan ulaz odbije. allSettled uvijek rješava i izvještava o svakom ishodu. race usvaja prvi utvrđeni rezultat. any treba jedan uspjeh, inače baca AggregateError.

Oba koriste isto obećanje. await pauze unutar asinkrone funkcije, tako da rezultati završavaju u običnim varijablama, a pogreške dospijevaju u try and catch blok.

Rijetko. Generator Funkcije s yield su nekada pokretale biblioteke poput co, ali async i await taj posao izvorno pokrivaju. Generatori dalje odgovaraju lijenim sekvencama i prilagođenim iteratorima.

util.promisify izravno pretvara funkciju u stilu povratnog poziva, a moduli poput fs.promises već vraćaju obećanja. Oba zamjenjuju gore prikazanu q biblioteku.

Da. Analizatori strojnog učenja označavaju lance bez rukovatelja odbacivanjem, čekaju unutar petlji i zapisuju ovisno o redoslijedu, a zatim rangiraju nalaze tako ispitivanja krenuti najrizičnijim stazama.

GitHub kopilot i slični agentski asistenti brzo prepisuju ugniježđene povratne pozive kao await pozive, no svako prepisivanje zahtijeva pregled zbog putanja pogrešaka i put semantika se tiho mijenja.

Sažmite ovu objavu uz: