Nelle esercitazioni precedenti, avresti visto le funzioni di callback utilizzate per gli eventi asincroni. Ma a volte le funzioni di callback possono diventare un incubo quando iniziano a essere annidate e il programma inizia a diventare lungo e complesso.
In questo tutorial imparerai-
- Cosa sono le promesse?
- Richiami alle promesse
- Trattare con promesse annidate
- Creare una promessa personalizzata
Cosa sono le promesse?
Prima di iniziare con le promesse, rivisitiamo prima cosa sono le funzioni di "callback" in Node.js. Abbiamo visto spesso queste funzioni di callback nei capitoli precedenti, quindi esaminiamone rapidamente una.
L'esempio seguente mostra uno snippet di codice, che viene utilizzato per connettersi a un database MongoDB ed eseguire un'operazione di aggiornamento su uno dei record nel database.
-
Nel codice precedente, la parte della funzione (err, db) è nota come dichiarazione di una funzione anonima o di callback. Quando MongoClient crea una connessione al database MongoDB, tornerà alla funzione di callback una volta completata l'operazione di connessione. Quindi, in un certo senso, le operazioni di connessione avvengono in background e, al termine, chiama la nostra funzione di callback. Ricorda che questo è uno dei punti chiave di Node.js per consentire a molte operazioni di svolgersi contemporaneamente e quindi non impedire a nessun utente di eseguire un'operazione.
-
Il secondo blocco di codice è ciò che viene eseguito quando la funzione di callback viene effettivamente chiamata. La funzione di callback aggiorna solo un record nel nostro database MongoDB.
Allora cos'è una promessa? Bene, una promessa è solo un miglioramento delle funzioni di callback in Node.js. Durante il ciclo di vita dello sviluppo, potrebbe esserci un'istanza in cui è necessario nidificare più funzioni di callback insieme. Questo può diventare un po 'disordinato e difficile da mantenere in un certo momento. In breve, una promessa è un miglioramento dei callback che mira ad alleviare questi problemi.
La sintassi di base di una promessa è mostrata di seguito;
var promise = doSomethingAync()promise.then(onFulfilled, onRejected)
- "doSomethingAync" è qualsiasi funzione di callback o asincrona che esegue una sorta di elaborazione.
- Questa volta, quando si definisce la richiamata, viene restituito un valore chiamato "promessa".
- Quando una promessa viene restituita, può avere 2 uscite. Questo è definito dalla "clausola then". O l'operazione può essere un successo che è indicato dal parametro "onFulfilled". Oppure può avere un errore che è indicato dal parametro "onRejected".
Nota: quindi l'aspetto chiave di una promessa è il valore restituito. Non esiste il concetto di un valore restituito quando si lavora con normali callback in Node.js. A causa del valore restituito, abbiamo un maggiore controllo su come definire la funzione di callback.
Nel prossimo argomento, vedremo un esempio di promesse e come traggono vantaggio dai callback.
Richiami alle promesse
Ora diamo un'occhiata a un esempio di come possiamo usare "promesse" dall'interno di un'applicazione Node.js. Per poter utilizzare le promesse in un'applicazione Node.js, il modulo "promise" deve essere prima scaricato e installato.
Modificheremo quindi il nostro codice come mostrato di seguito, che aggiorna un Employeename nella raccolta "Employee" utilizzando le promesse.
Passaggio 1) Installazione dei moduli NPM
Per utilizzare Promises dall'interno di un'applicazione Node JS, è necessario il modulo promise. Per installare il modulo promise, esegui il comando seguente
promessa di installazione di npm
Passaggio 2) Modifica il codice per includere le promesse
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"}});});
Spiegazione del codice: -
- La prima parte consiste nell'includere il modulo "promise" che ci consentirà di utilizzare la funzionalità di promessa nel nostro codice.
- Ora possiamo aggiungere la funzione "then" alla nostra funzione MongoClient.connect. Quindi ciò che fa è che quando viene stabilita la connessione al database, dobbiamo eseguire lo snippet di codice definito successivamente.
- Infine, definiamo il nostro frammento di codice che esegue il lavoro di aggiornamento EmployeeName del dipendente con il nome "Martin" in "Mohan".
Nota:-
Se ora controlli il contenuto del tuo database MongoDB, scoprirai che se esiste un record con EmployeeName di "Martin", verrà aggiornato a "Mohan".
Per verificare che i dati siano stati inseriti correttamente nel database, è necessario eseguire i seguenti comandi in MongoDB
- Usa EmployeeDB
- db.Employee.find ({EmployeeName: Mohan})
La prima istruzione garantisce la connessione al database EmployeeDb. La seconda istruzione cerca il record che ha il nome del dipendente "Mohan".
Trattare con promesse annidate
Quando si definiscono le promesse, è necessario notare che il metodo "allora" stesso restituisce una promessa. Quindi, in un certo senso, le promesse possono essere annidate o concatenate l'una all'altra.
Nell'esempio seguente, utilizziamo il concatenamento per definire 2 funzioni di callback, che inseriscono entrambe un record nel database MongoDB.
( Nota : il concatenamento è un concetto utilizzato per collegare tra loro l'esecuzione di metodi. Supponiamo che la tua applicazione avesse due metodi chiamati "metodoA" e "metodoB". E la logica era tale che "metodoB" dovrebbe essere chiamato dopo "metodoA", quindi concatenate l'esecuzione in modo tale che "metodoB" venga chiamato direttamente dopo "metodoA.")
La cosa fondamentale da notare in questo esempio è che il codice diventa più pulito, leggibile e gestibile utilizzando promesse annidate.
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"})})});
Spiegazione del codice: -
- Stiamo ora definendo 2 clausole "then" che vengono eseguite una dopo l'altra. Nella prima clausola then, stiamo passando il parametro 'db' che contiene la nostra connessione al database. Stiamo quindi utilizzando la proprietà di raccolta della connessione "db" per inserire i record nella raccolta "Dipendente". Il metodo "insertOne" viene utilizzato per inserire il documento effettivo nella raccolta Employee.
- Stiamo quindi utilizzando la seconda clausola quindi anche per inserire un altro record nel database.
Se ora controlli il contenuto del tuo database MongoDB, troverai i 2 record inseriti nel database MongoDB.
Creare una promessa personalizzata
È possibile creare una promessa personalizzata utilizzando un modulo nodo chiamato "q". La libreria "q" deve essere scaricata e installata utilizzando il gestore di pacchetti del nodo. Dopo aver utilizzato la libreria 'q', è possibile chiamare il metodo "denodeify" che farà sì che qualsiasi funzione diventi una funzione che restituisce una promessa.
Nell'esempio seguente, creeremo una semplice funzione chiamata "Aggiungi" che aggiungerà 2 numeri. Convertiremo questa funzione in una funzione per restituire una promessa.
Fatto ciò, useremo la promessa restituita dalla funzione Aggiungi per visualizzare un messaggio in console.log.
Seguiamo i passaggi seguenti per creare la nostra funzione personalizzata per restituire una promessa.
Passaggio 1) Installazione dei moduli NPM
Per utilizzare "q" dall'interno di un'applicazione Node JS, è necessario il modulo "q". Per installare il modulo "q", esegui il comando seguente
npm installa q
Passaggio 2) Definire il codice seguente che verrà utilizzato per creare la promessa personalizzata.
Spiegazione del codice: -
- Il primo bit consiste nell'includere la libreria "q" utilizzando la parola chiave require. Utilizzando questa libreria, saremo in grado di definire qualsiasi funzione per restituire una richiamata.
- Stiamo creando una funzione chiamata Aggiungi che aggiungerà 2 numeri definiti nelle variabili a e b. La somma di questi valori verrà memorizzata nella variabile c.
- Stiamo quindi utilizzando la libreria q per denodeificare (il metodo utilizzato per convertire qualsiasi funzione in una funzione che restituirebbe una promessa) la nostra funzione Aggiungi o altrimenti convertire la nostra funzione Aggiungi in una funzione che restituisce una promessa.
- Ora chiamiamo la nostra funzione "Aggiungi" e siamo in grado di ottenere un valore di promessa di ritorno a causa del passaggio precedente che abbiamo eseguito per denodeificare la funzione Aggiungi.
- La parola chiave "then" specifica che, se la funzione viene eseguita correttamente, visualizzare la stringa "Funzione aggiunta completata" nel file console.log.
Quando il codice precedente viene eseguito, l'output "Funzione di aggiunta completata" verrà visualizzato nel file console.log come mostrato di seguito.
Sommario
- L'utilizzo delle funzioni di callback in Node.js ha i suoi svantaggi. A volte durante il processo di sviluppo, l'uso annidato delle funzioni di callback può rendere il codice più complicato e difficile da mantenere.
- La maggior parte dei problemi con le funzioni di callback annidate può essere mitigata con l'uso di promesse e generatori in node.js
- Una Promise è un valore restituito da una funzione asincrona per indicare il completamento dell'elaborazione eseguita dalla funzione asincrona.
- Le promesse possono essere annidate l'una nell'altra per rendere il codice migliore e più facile da mantenere quando una funzione asincrona deve essere chiamata dopo un'altra funzione asincrona