Κατανόηση του σύγχρονου και ασύγχρονου JavaScript - Μέρος 1
Σύγχρονος και ασύγχρονη είναι σύγχυση έννοιες στο JavaScript, ειδικά για αρχάριους. Δύο ή περισσότερα πράγματα είναι σύγχρονος όταν αυτοί συμβεί ταυτόχρονα (σε συγχρονισμό), και ασύγχρονα όταν δεν το κάνουν (όχι σε συγχρονισμό).
Παρόλο που αυτοί οι ορισμοί είναι εύκολο να εισαχθούν, είναι στην πραγματικότητα πιο περίπλοκο από ό, τι φαίνεται. Πρέπει να λάβουμε υπόψη μας τι ακριβώς είναι σε συγχρονισμό, και τι δεν είναι.
Πιθανότατα να καλέσετε ένα κανονικός
λειτουργία σε JavaScript σύγχρονη, σωστά; Και αν είναι κάτι σαν setTimeout ()
ή το AJAX με το οποίο εργάζεστε, θα το αναφέρετε ως ασύγχρονο, ναι; Αν σου το πω και τα δυο είναι ασύγχρονα με κάποιο τρόπο?
Για να εξηγήσω το Γιατί, πρέπει να απευθυνθούμε στον κ. Χ για βοήθεια.
Σενάριο 1 - Ο κ. Χ προσπαθεί να συγχρονίσει
Εδώ είναι η ρύθμιση:
- Ο κ. Χ είναι κάποιος που μπορεί να απαντήσει σε δύσκολες ερωτήσεις και να εκτελέσει οποιαδήποτε ζητούμενη εργασία.
- Ο μόνος τρόπος για να επικοινωνήσετε μαζί του είναι μέσω τηλεφωνικής κλήσης.
- Όποια και αν είναι η ερώτηση ή η αποστολή σας, προκειμένου να ζητήσετε βοήθεια από τον κ. X για να το εκτελέσετε. τον καλείτε.
- Ο κ. Χ σας δίνει την απάντηση ή ολοκληρώνει την εργασία αμέσως, και σας ενημερώνει έγινε.
- Κάνατε τον παραλήπτη να αισθάνεται ικανοποιημένος και βγαίνετε για μια ταινία.
Αυτό που μόλις κάνατε ήταν α συγχρονισμένη (εμπρός και πίσω) επικοινωνία με τον κ. X. Ακούστηκε καθώς του ρωτούσατε την ερώτησή σας, και άκουγες όταν το απαντούσε.
Σενάριο 2 - Ο κ. X δεν είναι ευχαριστημένος με τη συγχρονικότητα
Δεδομένου ότι ο κ. Χ είναι τόσο αποτελεσματικός, αρχίζει να λαμβάνει πολλές ακόμα κλήσεις. Λοιπόν, τι συμβαίνει όταν τον αποκαλείτε αλλά είναι ήδη απασχολημένος μιλώντας σε κάποιον άλλο; Δεν θα μπορέσετε να του ρωτήσετε την ερώτησή σας - μέχρι να είναι ελεύθερος να λάβει την κλήση σας. Το μόνο που θα ακούσετε είναι ένας τόνος πολυάσχολος.
Τι κάνει ο κ. Χ για να καταπολεμήσει αυτό το θέμα?
Αντί να λαμβάνετε απευθείας κλήσεις:
- Ο κ. Χ μισθώνει έναν νέο άνθρωπο, τον κ. Μ και του δίδει έναν αυτόματο τηλεφωνητή για τους καλούντες να αφήνετε μηνύματα.
- Η δουλειά του κ. Μ είναι να διαβιβάσετε ένα μήνυμα από τον αυτόματο τηλεφωνητή στον κ. Χ όταν ξέρει ότι ο κ. Χ έχει τελειώσει τελείως την επεξεργασία όλων των προηγούμενων μηνυμάτων και είναι ήδη ελεύθερο να πάρει ένα νέο.
- Τώρα λοιπόν, όταν τον καλέσετε, αντί να πάρει έναν πολυάσχολο τόνο, θα αφήσετε ένα μήνυμα για τον κ. Χ, τότε περιμένετε να σας καλέσει πίσω (δεν υπάρχει ώρα ταινίας ακόμα).
- Μόλις ολοκληρωθεί ο κ. Χ με όλα τα μηνύματα που έρχονται από την ουρά σας πριν από τη δική σας, θα εξετάσει το θέμα σας και θα σε καλέσω πίσω για να σας δώσω μια απάντηση.
Τώρα εδώ βρίσκεται το ερώτημα: ήταν οι δράσεις μέχρι στιγμής σύγχρονη ή ασύγχρονη?
Είναι αναμεμειγμένο. Όταν άφησες το μήνυμά σου, Ο κ. Χ δεν το ακούει, οπότε η τέταρτη επικοινωνία ήταν ασύγχρονη.
Αλλά, όταν απάντησε, ήσασταν εκεί ακούγοντας, οι οποίες κάνει την επικοινωνία επιστροφής συγχρονισμένη.
Ελπίζω από τώρα να έχετε αποκτήσει μια καλύτερη κατανόηση του τρόπου με τον οποίο γίνεται αντιληπτός ο συγχρονισμός από την άποψη της επικοινωνίας. Ώρα να φέρει JavaScript.
JavaScript - μια γλώσσα ασύγχρονης προγραμματισμού
Όταν κάποιος χαρακτηρίζει τη JavaScript ως ασύγχρονη, αυτό στο οποίο αναφέρεται γενικά είναι ο τρόπος με τον οποίο μπορείτε Αφήστε ένα μήνυμα για αυτό, και δεν έχετε αποκλείσει την κλήση σας με έντονο τόνο.
Οι κλήσεις λειτουργίας είναι ποτέ κατευθείαν στο JavaScript, είναι κυριολεκτικά ολοκληρωμένα μέσω μηνυμάτων.
Το JavaScript χρησιμοποιεί α ουρά μηνυμάτων όπου κρατούνται εισερχόμενα μηνύματα (ή συμβάντα). Ενα event-loop (αποστολέας μηνυμάτων) αποστέλλει διαδοχικά αυτά τα μηνύματα σε ένα στοίβα κλήσεων όπου είναι οι αντίστοιχες λειτουργίες των μηνυμάτων στοιβάζονται ως πλαίσια (επιχειρήματα και μεταβλητές) για εκτέλεση.
Η στοίβα κλήσεων κρατά το πλαίσιο της αρχικής συνάρτησης που καλείται και οποιεσδήποτε άλλες καρέ για τις λειτουργίες που καλούνται μέσω ενωμένων κλήσεων στην κορυφή του .
Όταν ένα μήνυμα συνδέεται στην ουρά, περιμένει μέχρι να γίνει η στοίβα κλήσεων κενό όλων των πλαισίων από το προηγούμενο μήνυμα, και όταν είναι, το event-loop απενεργοποιεί το προηγούμενο μήνυμα, και προσθέτει τα αντίστοιχα πλαίσια του τρέχοντος μηνύματος στη στοίβα κλήσεων.
Το μήνυμα περιμένει ξανά μέχρι να γίνει η στοίβα κλήσεων άδειο από τα δικά του αντίστοιχα πλαίσια (δηλ. οι εκτελέσεις όλων των στοιχειοθετημένων λειτουργιών τελειώνουν), τότε αποσβένεται.
Εξετάστε τον ακόλουθο κώδικα:
λειτουργία foo () γραμμή λειτουργιών () foo (); λειτουργία baz () bar (); baz ();
Η λειτουργία που εκτελείται είναι baz ()
(στην τελευταία σειρά του αποσπάσματος κώδικα), για το οποίο ένα μήνυμα προστίθεται στην ουρά, και όταν το βρόχο συμβάντος το παίρνει, η στοίβα κλήσεων αρχίζει να στοιβάζονται πλαίσια Για baz ()
, μπαρ()
, και foo ()
στα σχετικά σημεία εκτέλεσης.
Μόλις ολοκληρωθεί η εκτέλεση των λειτουργιών μία προς μία, τα πλαίσια τους είναι από τη στοίβα κλήσεων, ενώ το μήνυμα είναι εξακολουθεί να περιμένει στην ουρά, μέχρι baz ()
από τη στοίβα.
Θυμηθείτε, οι κλήσεις λειτουργιών είναι ποτέ κατευθείαν στο JavaScript, έχουν τελειώσει μέσω μηνυμάτων. Έτσι κάθε φορά που ακούτε κάποιον να λέει ότι η ίδια η JavaScript είναι μια ασύγχρονη γλώσσα προγραμματισμού, υποθέστε ότι μιλάει για την ενσωματωμένη “τηλεφωνητής”, και πώς είστε ελεύθεροι να αφήσετε μηνύματα.
Αλλά τι γίνεται με τις συγκεκριμένες ασύγχρονες μεθόδους?
Μέχρι στιγμής δεν έχω αγγίξει API όπως setTimeout ()
και AJAX, αυτά είναι αυτά που είναι που αναφέρεται συγκεκριμένα ως ασύγχρονη. Γιατί αυτό?
Είναι σημαντικό να καταλάβετε τι είναι ακριβώς συγχρονισμένο ή ασύγχρονο. Το JavaScript, με τη βοήθεια συμβάντων και του βρόχου εκδήλωσης, μπορεί να εξασκηθεί ασύγχρονη επεξεργασία των μηνυμάτων, μα αυτό δεν σημαίνει τα παντα στο JavaScript είναι ασύγχρονη.
Θυμηθείτε, σας είπα ότι το μήνυμα δεν έφυγε μέχρι που ήταν η στοίβα κλήσεων άδειο από τα αντίστοιχα πλαίσια, όπως και εσείς δεν έφυγε για μια ταινία μέχρι να πάρετε την απάντησή σας - αυτό είναι είναι σύγχρονα, είστε εκεί περιμένοντας έως ότου ολοκληρωθεί η εργασία, και θα λάβετε την απάντηση.
Αναμονή δεν είναι ιδανική σε όλα τα σενάρια. Τι γίνεται αν μετά την αποχώρηση ενός μηνύματος, αντί να περιμένετε, μπορείτε να φύγετε για την ταινία; Τι γίνεται αν μια λειτουργία μπορεί να αποσυρθεί (εκκενώνοντας τη στοίβα κλήσεων) και το μήνυμά της μπορεί να αφαιρεθεί ακόμα και πριν ολοκληρωθεί η εργασία της λειτουργίας; Τι γίνεται αν μπορείτε να εκτελέσετε τον κώδικα ασύγχρονα?
Αυτό είναι όπου API όπως setTimeout ()
και η AJAX μπαίνουν στην εικόνα και αυτό που κάνουν είναι ... κρατήστε το, δεν μπορώ να το εξηγήσω χωρίς να επιστρέψω στον κ. X, το οποίο θα δούμε στο δεύτερο μέρος αυτού του άρθρου. Μείνετε συντονισμένοι.