Node.js Generators & Compare with Callbacks

Σε αυτό το σεμινάριο, θα μάθουμε για Generators και οι διαφορές τους με τα Callbacks

Τι είναι οι γεννήτριες;

Generatorέχουν γίνει αρκετά διάσημοι σε Node.js τον τελευταίο καιρό και αυτό οφείλεται πιθανώς σε αυτό που είναι ικανοί να κάνουν.

  • GeneratorΤα s είναι εκτελέσεις συναρτήσεων που μπορούν να ανασταλούν και να συνεχιστούν σε μεταγενέστερο σημείο.
  • GeneratorΕίναι χρήσιμα κατά την εκτέλεση εννοιών όπως «τεμπέλης εκτέλεση». Αυτό ουσιαστικά σημαίνει ότι με την αναστολή της εκτέλεσης και τη συνέχιση κατά βούληση, είμαστε σε θέση να τραβήξουμε τιμές μόνο όταν χρειάζεται.

Generatorέχει τις παρακάτω 2 βασικές μεθόδους.

  1. Μέθοδος απόδοσης – Η μέθοδος απόδοσης καλείται σε μια συνάρτηση για να σταματήσει την εκτέλεση της συνάρτησης στη συγκεκριμένη γραμμή όπου καλείται η μέθοδος απόδοσης.
  2. Επόμενη μέθοδος – Αυτή η μέθοδος καλείται από την κύρια εφαρμογή για να συνεχίσει την εκτέλεση μιας συνάρτησης που έχει μέθοδο απόδοσης. Η εκτέλεση της συνάρτησης θα συνεχιστεί μέχρι την επόμενη μέθοδο απόδοσης ή μέχρι το τέλος της μεθόδου.

Ας δούμε ένα παράδειγμα για το πώς μπορούν να χρησιμοποιηθούν γεννήτριες.

Στο παράδειγμά μας, θα έχουμε μια απλή συνάρτηση Προσθήκη που θα προσθέσει 2 αριθμούς, αλλά θα συνεχίσουμε να σταματάμε την εκτέλεση της μεθόδου σε διαφορετικά σημεία για να δείξουμε πώς μπορούν να χρησιμοποιηθούν οι γεννήτριες.

Node.js Generators

function* Add(x) {
   yield x + 1;
   var y = yield(null);
   y = 6
   return x + y;
}

var gen = Add(5);

gen.next();

gen.next(); 

Επεξήγηση κώδικα

  1. Το πρώτο βήμα είναι να ορίσουμε τη «λειτουργία» της γεννήτριας μας. Σημειώστε ότι αυτό γίνεται προσθέτοντας ένα «*» στη λέξη-κλειδί συνάρτησης. Στη συνέχεια ορίζουμε μια συνάρτηση που ονομάζεται Προσθήκη η οποία παίρνει μια παράμετρο x.
  2. Η λέξη-κλειδί απόδοσης είναι συγκεκριμένη για γεννήτριες. Αυτό το καθιστά μια ισχυρή κατασκευή για την παύση μιας συνάρτησης στη μέση του οτιδήποτε. Εδώ λοιπόν, η εκτέλεση της συνάρτησης θα σταματήσει μέχρι να καλέσουμε τη συνάρτηση next(), η οποία θα γίνει στο Βήμα 4. Σε αυτό το σημείο, η τιμή του x θα γίνει 6 και η εκτέλεση της συνάρτησης θα σταματήσει.
  3. Εδώ καλούμε πρώτα τη συνάρτηση γεννήτριας και στέλνουμε την τιμή 5 στη συνάρτηση Προσθήκη. Αυτή η τιμή θα αντικατασταθεί στην παράμετρο x της συνάρτησης Προσθήκη.
  4. Μόλις καλέσουμε τη συνάρτηση next(), η συνάρτηση Add() θα συνεχίσει την εκτέλεση. Όταν εκτελεστεί η επόμενη πρόταση var y= yield(null), η συνάρτηση Add() θα σταματήσει και πάλι να εκτελείται.
  5. Τώρα αφού καλέσετε ξανά τη συνάρτηση next(), θα εκτελεστούν οι επόμενες εντολές και η συνδυασμένη τιμή των x=5 και y=6 θα προστεθεί και θα επιστραφεί.

Επανακλήσεις έναντι γεννητριών

GeneratorΤα s χρησιμοποιούνται για την επίλυση του προβλήματος αυτού που είναι γνωστό ως callback hell. Μερικές φορές οι συναρτήσεις επανάκλησης γίνονται τόσο ένθετες κατά την ανάπτυξη μιας εφαρμογής Node.js που γίνεται πολύ περίπλοκη η χρήση συναρτήσεων επανάκλησης.

Εδώ είναι χρήσιμες οι γεννήτριες. Ένα από τα πιο συνηθισμένα παραδείγματα αυτού είναι κατά τη δημιουργία συναρτήσεων χρονοδιακόπτη.

Ας δούμε το παρακάτω παράδειγμα για το πώς οι γεννήτριες μπορούν να αποδειχθούν χρήσιμες σε σχέση με τις επανακλήσεις.

Το παράδειγμά μας θα δημιουργήσει απλώς μια απλή λειτουργία χρονικής καθυστέρησης. Στη συνέχεια θα θέλαμε να καλέσουμε αυτή τη συνάρτηση ενσωματώνοντας καθυστέρηση 1000, 2000 και 3000 ms.

Βήμα 1) Καθορίστε τη λειτουργία επανάκλησης με τον απαραίτητο κωδικό χρονικής καθυστέρησης.

Επανακλήσεις vs. Generators

function Timedelay(ptime, callback) {

setTimeout(function() {
  
    callback("Pausing for " + ptime);
    
  }, time);
}

Επεξήγηση κώδικα

  1. Εδώ δημιουργούμε μια συνάρτηση που ονομάζεται Timedelay με μια παράμετρο που ονομάζεται ptime. Αυτό θα πάρει την απαραίτητη χρονική καθυστέρηση που θέλουμε να εισάγουμε στην αίτησή μας.
  2. Το επόμενο βήμα είναι να δημιουργήσετε απλώς ένα μήνυμα, το οποίο θα εμφανιστεί στον χρήστη λέγοντας ότι η εφαρμογή θα τεθεί σε παύση για αυτούς τους πολλούς αριθμούς χιλιοστών του δευτερολέπτου.

Βήμα 2) Τώρα ας δούμε τον κωδικό αν ενσωματώναμε επανάκληση. Ας υποθέσουμε ότι θέλαμε να ενσωματώσουμε επανακλήσεις με βάση την τιμή των 1000, 2000 και 3000 χιλιοστών του δευτερολέπτου, ο παρακάτω κώδικας δείχνει πώς θα χρειαζόμασταν να τις εφαρμόσουμε χρησιμοποιώντας επιστροφές κλήσης.

Επανακλήσεις vs. Generators

Timedelay(1000, function(message) {
  
  console.log(msg);
  Timedelay(2000, function(message) {
    
    console.log(msg);
    Timedelay(3000, function(message) {
      
      console.log(msg);
  })
  })
})

Επεξήγηση κώδικα

  1. Καλούμε το Timedelay ως επιστροφή κλήσης με 1000 ως τιμή.
  2. Στη συνέχεια θέλουμε να καλέσουμε ξανά τη συνάρτηση Timedelay με το 2000 ως τιμή.
  3. Τέλος, θέλουμε να καλέσουμε ξανά τη συνάρτηση Timedelay με 3000 ως τιμή.

Από τον παραπάνω κώδικα, μπορείτε να δείτε ότι γίνεται πιο βρώμικο καθώς θέλουμε να αρχίσουμε να καλούμε τη συνάρτηση πολλές φορές.

Βήμα 3) Τώρα ας δούμε πώς να εφαρμόσουμε τον ίδιο κώδικα χρησιμοποιώντας γεννήτριες. Από τον παρακάτω κώδικα μπορείτε τώρα να δείτε πόσο απλό έχει γίνει η υλοποίηση της συνάρτησης Timedelay χρησιμοποιώντας γεννήτριες.

Επανακλήσεις vs. Generators

function* Messages() {
  console,log(yield(Timedelay(1000, function(){})));
  console,log(yield(Timedelay(2000, function(){})));
  console,log(yield(Timedelay(3000, function(){})));
}

Επεξήγηση κώδικα

  1. Αρχικά ορίζουμε μια συνάρτηση γεννήτριας που θα χρησιμοποιηθεί για την κλήση της συνάρτησης Timedelay.
  2. Καλούμε τη συνάρτηση Yield μαζί με τη συνάρτηση Timedelay με το 1000 ως τιμή παραμέτρου.
  3. Στη συνέχεια καλούμε τη συνάρτηση απόδοσης μαζί με τη συνάρτηση Timedelay με το 2000 ως τιμή παραμέτρου.
  4. Τέλος, καλούμε τη συνάρτηση Yield μαζί με τη συνάρτηση Timedelay με 3000 ως τιμή παραμέτρου.

Σύνοψη

GeneratorΤο s μπορεί επίσης να χρησιμοποιηθεί για την ανακούφιση των προβλημάτων με τις ένθετες επανακλήσεις και να βοηθήσει στην αφαίρεση αυτού που είναι γνωστό ως η κόλαση της επανάκλησης. GeneratorΤα s χρησιμοποιούνται για να σταματήσουν την επεξεργασία μιας συνάρτησης. Αυτό επιτυγχάνεται με τη χρήση της μεθόδου 'απόδοσης' στην ασύγχρονη συνάρτηση.