Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

Γεια σε όλους. Σε επαφή Omelnitsky Sergey. Όχι πολύ καιρό πριν, φιλοξένησα μια ροή σχετικά με τον αντιδραστικό προγραμματισμό, όπου μίλησα για τον ασύγχρονο σε JavaScript. Σήμερα θα ήθελα να συνοψίσω αυτό το υλικό.

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

Πριν όμως ξεκινήσουμε το κύριο υλικό, πρέπει να κάνουμε μια εισαγωγή. Ας ξεκινήσουμε λοιπόν με τους ορισμούς: τι είναι η στοίβα και η ουρά;

Σωρός είναι μια συλλογή της οποίας τα στοιχεία ανακτώνται με βάση το «last in, first out» LIFO

Στροφή είναι μια συλλογή της οποίας τα στοιχεία λαμβάνονται σύμφωνα με την αρχή («first in, first out» FIFO

Εντάξει, ας συνεχίσουμε.

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

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

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

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

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

Ας ρίξουμε μια ματιά στο παρακάτω παράδειγμα και ας το δούμε βήμα προς βήμα. Ας δούμε επίσης τι συμβαίνει στο σύστημα.

console.log('Hi');
setTimeout(function cb1() {
    console.log('cb1');
}, 5000);
console.log('Bye');

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

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

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

2) Στη συνέχεια, η εντολή console.log('Hi') προστίθεται στη στοίβα κλήσεων.

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

3) Και εκπληρώνεται

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

4) Στη συνέχεια, το console.log('Hi') αφαιρείται από τη στοίβα κλήσεων.

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

5) Τώρα ας προχωρήσουμε στην εντολή setTimeout(function cb1() {… }). Προστίθεται στη στοίβα κλήσεων.

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

6) Εκτελείται η εντολή setTimeout(function cb1() {… }). Το πρόγραμμα περιήγησης δημιουργεί ένα χρονόμετρο που αποτελεί μέρος του Web API. Θα εκτελέσει αντίστροφη μέτρηση.

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

7) Η εντολή setTimeout(function cb1() {… }) ολοκλήρωσε την εργασία της και αφαιρέθηκε από τη στοίβα κλήσεων.

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

8) Η εντολή console.log('Bye') προστίθεται στη στοίβα κλήσεων.

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

9) Η εντολή console.log('Bye') εκτελείται.

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

10) Η εντολή console.log('Bye') αφαιρείται από τη στοίβα κλήσεων.

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

11) Αφού περάσουν τουλάχιστον 5000 ms, ο χρονοδιακόπτης τελειώνει και τοποθετεί την επανάκληση cb1 στην ουρά επανάκλησης.

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

12) Ο βρόχος συμβάντος παίρνει τη συνάρτηση cb1 από την ουρά επανάκλησης και την ωθεί στη στοίβα κλήσεων.

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

13) Η συνάρτηση cb1 εκτελείται και προσθέτει το console.log('cb1') στη στοίβα κλήσεων.

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

14) Η εντολή console.log('cb1') εκτελείται.

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

15) Η εντολή console.log('cb1') αφαιρείται από τη στοίβα κλήσεων.

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

16) Η συνάρτηση cb1 αφαιρείται από τη στοίβα κλήσεων.

Ας δούμε ένα παράδειγμα στη δυναμική:

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

Λοιπόν, εξετάσαμε πώς εφαρμόζεται ο ασυγχρονισμός στο JavaScript. Τώρα ας μιλήσουμε εν συντομία για την εξέλιξη του ασύγχρονου κώδικα.

Η εξέλιξη του ασύγχρονου κώδικα.

a(function (resultsFromA) {
    b(resultsFromA, function (resultsFromB) {
        c(resultsFromB, function (resultsFromC) {
            d(resultsFromC, function (resultsFromD) {
                e(resultsFromD, function (resultsFromE) {
                    f(resultsFromE, function (resultsFromF) {
                        console.log(resultsFromF);
                    })
                })
            })
        })
    })
});

Ο ασύγχρονος προγραμματισμός όπως τον ξέρουμε στο JavaScript μπορεί να γίνει μόνο με συναρτήσεις. Μπορούν να περάσουν όπως κάθε άλλη μεταβλητή σε άλλες συναρτήσεις. Έτσι γεννήθηκαν τα callbacks. Και είναι δροσερό, διασκεδαστικό και ένθερμο, μέχρι που μετατρέπεται σε θλίψη, μελαγχολία και θλίψη. Γιατί; Ναι, είναι απλό:

  • Καθώς η πολυπλοκότητα του κώδικα μεγαλώνει, το έργο μετατρέπεται γρήγορα σε σκοτεινά πολλαπλά ένθετα μπλοκ - "callback hell".
  • Ο χειρισμός σφαλμάτων μπορεί εύκολα να παραβλεφθεί.
  • Δεν μπορείτε να επιστρέψετε εκφράσεις με επιστροφή.

Με την εμφάνιση του Promise, η κατάσταση έχει γίνει λίγο καλύτερη.

new Promise(function(resolve, reject) {
    setTimeout(() => resolve(1), 2000);

}).then((result) => {
    alert(result);
    return result + 2;

}).then((result) => {
    throw new Error('FAILED HERE');
    alert(result);
    return result + 2;

}).then((result) => {
    alert(result);
    return result + 2;

}).catch((e) => {
    console.log('error: ', e);
});

  • Εμφανίστηκαν αλυσίδες υποσχέσεων, οι οποίες βελτίωσαν την αναγνωσιμότητα του κώδικα
  • Υπήρχε ξεχωριστή μέθοδος παρακολούθησης σφαλμάτων
  • Παράλληλη εκτέλεση με προσθήκη Promise.all
  • Μπορούμε να λύσουμε ένθετο ασυγχρονισμό με async/wait

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

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

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

Αντιδραστικός προγραμματισμός - ένα πρότυπο προγραμματισμού που επικεντρώνεται στις ροές δεδομένων και στη διάδοση αλλαγών. Ας ρίξουμε μια πιο προσεκτική ματιά στο τι είναι μια ροή δεδομένων.

// Получаем ссылку на элемент
const input = ducument.querySelector('input');

const eventsArray = [];

// Пушим каждое событие в массив eventsArray
input.addEventListener('keyup',
    event => eventsArray.push(event)
);

Ας φανταστούμε ότι έχουμε ένα πεδίο εισαγωγής. Δημιουργούμε έναν πίνακα και για κάθε keyup του συμβάντος εισόδου, θα αποθηκεύουμε το συμβάν στον πίνακα μας. Ταυτόχρονα, θα ήθελα να σημειώσω ότι ο πίνακας μας ταξινομείται κατά χρόνο, δηλ. ο δείκτης των μεταγενέστερων γεγονότων είναι μεγαλύτερος από τον δείκτη των προηγούμενων γεγονότων. Ένας τέτοιος πίνακας είναι ένα απλοποιημένο μοντέλο ροής δεδομένων, αλλά δεν είναι ακόμη ροή. Προκειμένου αυτή η συστοιχία να ονομάζεται με ασφάλεια ροή, πρέπει να μπορεί με κάποιο τρόπο να ενημερώνει τους συνδρομητές ότι έχουν φτάσει νέα δεδομένα σε αυτήν. Έτσι φτάνουμε στον ορισμό της ροής.

Ροή δεδομένων

const { interval } = Rx;
const { take } = RxOperators;

interval(1000).pipe(
    take(4)
)

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

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

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

RxJS είναι μια βιβλιοθήκη για εργασία με ασύγχρονα προγράμματα και προγράμματα που βασίζονται σε συμβάντα χρησιμοποιώντας παρατηρήσιμες ακολουθίες. Η βιβλιοθήκη παρέχει τον κύριο τύπο Αισθητός, αρκετοί τύποι βοηθών (Παρατηρητές, Προγραμματιστές, Υποκείμενα) και χειριστές για εργασία με εκδηλώσεις όπως και με συλλογές (χάρτης, φιλτράρισμα, μείωση, κάθε και παρόμοια από το JavaScript Array).

Ας κατανοήσουμε τις βασικές έννοιες αυτής της βιβλιοθήκης.

Παρατηρήσιμος, Παρατηρητής, Παραγωγός

Το Observable είναι ο πρώτος τύπος βάσης που θα εξετάσουμε. Αυτή η κλάση περιέχει το κύριο μέρος της υλοποίησης RxJs. Συνδέεται με μια παρατηρήσιμη ροή, στην οποία μπορείτε να εγγραφείτε χρησιμοποιώντας τη μέθοδο εγγραφής.

Το Observable υλοποιεί έναν βοηθητικό μηχανισμό δημιουργίας ενημερώσεων, το λεγόμενο Παρατηρητής. Η πηγή των τιμών για έναν Παρατηρητή ονομάζεται Παραγωγός. Μπορεί να είναι ένας πίνακας, ένας επαναλήπτης, μια υποδοχή web, κάποιο είδος συμβάντος κ.λπ. Μπορούμε λοιπόν να πούμε ότι το παρατηρήσιμο είναι ένας αγωγός μεταξύ Παραγωγού και Παρατηρητή.

Το Observable χειρίζεται τρία είδη συμβάντων Observer:

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

Ας δούμε ένα demo:

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

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

Το να σκέφτεσαι δύνατα

Και τότε συνειδητοποίησα ότι ήταν πιο ενδιαφέρον να το πω παρά να το γράψω. 😀

Συνδρομή

Όταν εγγραφούμε σε μια ροή, δημιουργούμε μια νέα τάξη συνδρομή, που μας δίνει την επιλογή να διαγραφούμε με τη μέθοδο διαγραφείτε. Μπορούμε επίσης να ομαδοποιήσουμε τις συνδρομές χρησιμοποιώντας τη μέθοδο προσθέτω. Λοιπόν, είναι λογικό να μπορούμε να καταργήσουμε την ομαδοποίηση των νημάτων χρησιμοποιώντας αφαιρέστε. Οι μέθοδοι προσθήκης και αφαίρεσης δέχονται μια διαφορετική συνδρομή ως είσοδο. Θα ήθελα να σημειώσω ότι όταν καταργούμε τη συνδρομή, καταργούμε την εγγραφή από όλες τις θυγατρικές συνδρομές σαν να αποκαλούσαν επίσης τη μέθοδο κατάργησης εγγραφής. Προχώρα.

Τύποι ρεμάτων

ΚΑΥΤΌ
ΚΡΥΟ

Ο παραγωγός δημιουργείται έξω από το παρατηρήσιμο
Ο παραγωγός δημιουργείται μέσα σε παρατηρήσιμο

Τα δεδομένα διαβιβάζονται τη στιγμή που δημιουργείται το παρατηρήσιμο
Τα δεδομένα παρέχονται κατά τη στιγμή της συνδρομής.

Χρειάζεστε περισσότερη λογική για να διαγραφείτε
Το νήμα τελειώνει από μόνο του

Χρησιμοποιεί μια σχέση ένα προς πολλά
Χρησιμοποιεί μια σχέση ένας προς έναν

Όλες οι συνδρομές έχουν την ίδια αξία
Οι συνδρομές είναι ανεξάρτητες

Τα δεδομένα μπορούν να χαθούν εάν δεν υπάρχει συνδρομή
Επανεκδίδει όλες τις τιμές ροής για μια νέα συνδρομή

Για να δώσω μια αναλογία, θα φανταζόμουν ένα hot stream σαν ταινία σε κινηματογράφο. Σε ποια χρονική στιγμή ήρθες, από εκείνη τη στιγμή άρχισες να παρακολουθείς. Θα συγκρίνω ένα κρύο ρεύμα με μια κλήση σε αυτά. υποστήριξη. Οποιοσδήποτε καλεί ακούει την εγγραφή του τηλεφωνητή από την αρχή μέχρι το τέλος, αλλά μπορείτε να κλείσετε το τηλέφωνο με διαγραφή.

Θα ήθελα να σημειώσω ότι υπάρχουν επίσης τα λεγόμενα θερμά ρεύματα (έχω συναντήσει έναν τέτοιο ορισμό εξαιρετικά σπάνια και μόνο σε ξένες κοινότητες) - αυτό είναι ένα ρεύμα που μετατρέπεται από ένα κρύο ρεύμα σε ένα ζεστό. Τίθεται το ερώτημα - πού να το χρησιμοποιήσετε)) ​​Θα δώσω ένα παράδειγμα από την πρακτική.

Δουλεύω με την Angular. Χρησιμοποιεί ενεργά rxjs. Για τη λήψη δεδομένων στον διακομιστή, περιμένω μια ψυχρή ροή και χρησιμοποιώ αυτήν τη ροή στο πρότυπο χρησιμοποιώντας το asyncPipe. Εάν χρησιμοποιήσω αυτόν τον σωλήνα αρκετές φορές, τότε, επιστρέφοντας στον ορισμό του ψυχρού ρεύματος, κάθε σωλήνας θα ζητήσει δεδομένα από τον διακομιστή, κάτι που είναι τουλάχιστον περίεργο. Και αν μετατρέψω ένα κρύο ρεύμα σε ζεστό, τότε το αίτημα θα γίνει μία φορά.

Γενικά, η κατανόηση του τύπου των ροών είναι αρκετά δύσκολη για αρχάριους, αλλά σημαντική.

Οι φορείς εκμετάλλευσης

return this.http.get(`${environment.apiUrl}/${this.apiUrl}/trade_companies`)
    .pipe(
        tap(({ data }: TradeCompanyList) => this.companies$$.next(cloneDeep(data))),
        map(({ data }: TradeCompanyList) => data)
    );

Οι χειριστές μας παρέχουν την ευκαιρία να εργαστούμε με ροές. Βοηθούν στον έλεγχο των γεγονότων που ρέουν στο Παρατηρήσιμο. Θα εξετάσουμε μερικά από τα πιο δημοφιλή και περισσότερες πληροφορίες σχετικά με τους χειριστές μπορείτε να βρείτε στους συνδέσμους στις χρήσιμες πληροφορίες.

Χειριστές-του

Ας ξεκινήσουμε με τον βοηθητικό χειριστή του. Δημιουργεί ένα παρατηρήσιμο με βάση μια απλή τιμή.

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

Χειριστές-φίλτρο

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

Ο χειριστής του φίλτρου, όπως υποδηλώνει το όνομα, φιλτράρει το σήμα ροής. Εάν ο χειριστής επιστρέψει true, τότε παρακάμπτει περαιτέρω.

Χειριστές - πάρτε

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

take - Λαμβάνει την τιμή του αριθμού των εκπομπών, μετά την οποία τελειώνει η ροή.

Operators-debounceTime

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

debounceTime - απορρίπτει τις εκπεμπόμενες τιμές που εμπίπτουν στο καθορισμένο χρονικό διάστημα μεταξύ των δεδομένων εξόδου - αφού παρέλθει το χρονικό διάστημα, εκπέμπει την τελευταία τιμή.

const { Observable } = Rx;
const { debounceTime, take } = RxOperators;

Observable.create((observer) => {
  let i = 1;
  observer.next(i++);
  // Испускаем значение раз в 1000мс
  setInterval(() => {
    observer.next(i++)
  }, 1000);

 // Испускаем значение раз в 1500мс
  setInterval(() => {
    observer.next(i++)
  }, 1500);
}).pipe(
  debounceTime(700),  // Ожидаем 700мс значения прежде чем обработать
  take(3)
);  

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

Operators-takeWhile

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

Εκπέμπει τιμές μέχρι το takeWhile να επιστρέψει το false και μετά να καταργήσει την εγγραφή από τη ροή.

const { Observable } = Rx;
const { debounceTime, takeWhile } = RxOperators;

Observable.create((observer) => {
  let i = 1;
  observer.next(i++);
  // Испускаем значение раз в 1000мс
  setInterval(() => {
    observer.next(i++)
  }, 1000);
}).pipe(
  takeWhile( producer =>  producer < 5 )
);  

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

Operators-combineLatest

Ο συνδυασμένος τελεστής combinationLatest είναι κάπως παρόμοιος με το word.all. Συνδυάζει πολλαπλές ροές σε ένα. Αφού κάθε νήμα έχει κάνει τουλάχιστον μία εκπομπή, παίρνουμε τις πιο πρόσφατες τιμές από το καθένα ως πίνακα. Επιπλέον, μετά από οποιαδήποτε εκπομπή από τα συνδυασμένα ρεύματα, θα δώσει νέες τιμές.

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

const { combineLatest, Observable } = Rx;
const { take } = RxOperators;

const observer_1 = Observable.create((observer) => {
  let i = 1;
  // Испускаем значение раз в 1000мс
  setInterval(() => {
    observer.next('a: ' + i++);
  }, 1000);
});

const observer_2 = Observable.create((observer) => {
  let i = 1;
  // Испускаем значение раз в 750мс
  setInterval(() => {
    observer.next('b: ' + i++);
  }, 750);
});

combineLatest(observer_1, observer_2).pipe(take(5));

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

Operators-zip

Zip - περιμένει μια τιμή από κάθε ροή και σχηματίζει έναν πίνακα με βάση αυτές τις τιμές. Εάν η τιμή δεν προέρχεται από κανένα νήμα, τότε η ομάδα δεν θα σχηματιστεί.

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

const { zip, Observable } = Rx;
const { take } = RxOperators;

const observer_1 = Observable.create((observer) => {
  let i = 1;
  // Испускаем значение раз в 1000мс
  setInterval(() => {
    observer.next('a: ' + i++);
  }, 1000);
});

const observer_2 = Observable.create((observer) => {
  let i = 1;
  // Испускаем значение раз в 750
  setInterval(() => {
    observer.next('b: ' + i++);
  }, 750);
});

const observer_3 = Observable.create((observer) => {
  let i = 1;
  // Испускаем значение раз в 500
  setInterval(() => {
    observer.next('c: ' + i++);
  }, 500);
});

zip(observer_1, observer_2, observer_3).pipe(take(5));

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

Χειριστές - forkJoin

Το forkJoin ενώνει επίσης νήματα, αλλά εκπέμπει μια τιμή μόνο όταν ολοκληρωθούν όλα τα νήματα.

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

const { forkJoin, Observable } = Rx;
const { take } = RxOperators;

const observer_1 = Observable.create((observer) => {
  let i = 1;
  // Испускаем значение раз в 1000мс
  setInterval(() => {
    observer.next('a: ' + i++);
  }, 1000);
}).pipe(take(3));

const observer_2 = Observable.create((observer) => {
  let i = 1;
  // Испускаем значение раз в 750
  setInterval(() => {
    observer.next('b: ' + i++);
  }, 750);
}).pipe(take(5));

const observer_3 = Observable.create((observer) => {
  let i = 1;
  // Испускаем значение раз в 500
  setInterval(() => {
    observer.next('c: ' + i++);
  }, 500);
}).pipe(take(4));

forkJoin(observer_1, observer_2, observer_3);

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

Χάρτης χειριστή

Ο τελεστής μετασχηματισμού χάρτη μετατρέπει την τιμή εκπομπής σε νέα.

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

const {  Observable } = Rx;
const { take, map } = RxOperators;

Observable.create((observer) => {
  let i = 1;
  // Испускаем значение раз в 1000мс
  setInterval(() => {
    observer.next(i++);
  }, 1000);
}).pipe(
  map(x => x * 10),
  take(3)
);

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

Χειριστές - κοινή χρήση, πατήστε

Ο χειριστής βρύσης σάς επιτρέπει να κάνετε παρενέργειες, δηλαδή οποιεσδήποτε ενέργειες δεν επηρεάζουν τη σειρά.

Ο πάροχος κοινής ωφέλειας μπορεί να μετατρέψει ένα ψυχρό ρεύμα σε ζεστό.

Ασύγχρονος προγραμματισμός σε JavaScript (Callback, Promise, RxJs)

Οι χειριστές έχουν τελειώσει. Ας περάσουμε στο Θέμα.

Το να σκέφτεσαι δύνατα

Και μετά πήγα να πιω τσάι. Βαρέθηκα αυτά τα παραδείγματα 😀

Θεματική οικογένεια

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

  • επόμενο - διαβίβαση νέων δεδομένων στη ροή
  • σφάλμα - σφάλμα και τερματισμός νήματος
  • πλήρης - τέλος του νήματος
  • εγγραφείτε - εγγραφείτε σε μια ροή
  • κατάργηση εγγραφής - κατάργηση εγγραφής από το νήμα
  • asObservable - μεταμορφώνεται σε παρατηρητή
  • toPromise - μεταμορφώνεται σε υπόσχεση

Διαθέστε 4 5 είδη θεμάτων.

Το να σκέφτεσαι δύνατα

Είπα 4 στο stream, αλλά αποδείχτηκε ότι πρόσθεσαν ένα ακόμα. Όπως λέει και η παροιμία, ζήστε και μάθετε.

Απλό Θέμα new Subject()- το απλούστερο είδος θεμάτων. Δημιουργήθηκε χωρίς παραμέτρους. Περνά τις τιμές που ήρθαν μόνο μετά τη συνδρομή.

ΣυμπεριφοράΘέμα new BehaviorSubject( defaultData<T> ) - κατά τη γνώμη μου ο πιο συνηθισμένος τύπος θεμάτων. Η είσοδος παίρνει την προεπιλεγμένη τιμή. Αποθηκεύει πάντα τα δεδομένα του τελευταίου τεύχους, τα οποία μεταδίδονται κατά την εγγραφή. Αυτή η κλάση έχει επίσης μια μέθοδο χρήσιμης τιμής που επιστρέφει την τρέχουσα τιμή της ροής.

ReplaySubject new ReplaySubject(bufferSize?: number, windowTime?: number) - Προαιρετικά, μπορεί να λάβει ως πρώτο όρισμα το μέγεθος του buffer των τιμών που θα αποθηκεύσει από μόνο του και τη δεύτερη φορά κατά την οποία χρειαζόμαστε αλλαγές.

ασύγχρονο θέμα new AsyncSubject() - τίποτα δεν συμβαίνει κατά την εγγραφή και η τιμή θα επιστραφεί μόνο όταν ολοκληρωθεί. Θα επιστραφεί μόνο η τελευταία τιμή της ροής.

WebSocketSubject new WebSocketSubject(urlConfigOrSource: string | WebSocketSubjectConfig<T> | Observable<T>, destination?: Observer<T>) - Η τεκμηρίωση είναι σιωπηλή για αυτό και εγώ ο ίδιος το βλέπω για πρώτη φορά. Ποιος ξέρει τι κάνει, γράψε, θα προσθέσουμε.

Φτου. Λοιπόν, εξετάσαμε όλα όσα ήθελα να πω σήμερα. Ελπίζω ότι αυτές οι πληροφορίες ήταν χρήσιμες. Μπορείτε να διαβάσετε τη λίστα της βιβλιογραφίας μόνοι σας στην καρτέλα Χρήσιμες πληροφορίες.

χρήσιμες πληροφορίες

Πηγή: www.habr.com

Προσθέστε ένα σχόλιο