-
-
Notifications
You must be signed in to change notification settings - Fork 2
Promises & Async/Await #14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
33 commits
Select commit
Hold shift + click to select a range
ab9e91e
asyn/await
LazarosZiskos 98d9c2d
working on promises
LazarosZiskos 10d3367
finished promises
LazarosZiskos 019d8b7
Αλλαγή γένους promise
LazarosZiskos 687d6f9
Update docs-language/asynchronous/3. promises.md
LazarosZiskos d0b4cfe
Update docs-language/asynchronous/3. promises.md
LazarosZiskos a196139
Update docs-language/asynchronous/3. promises.md
LazarosZiskos c9daad2
Update docs-language/asynchronous/3. promises.md
LazarosZiskos 7f37b4d
Update docs-language/asynchronous/3. promises.md
LazarosZiskos 9d93eff
Update docs-language/asynchronous/3. promises.md
LazarosZiskos 8fd8004
Update docs-language/asynchronous/4. async-await.md
LazarosZiskos ba8bf8a
Update docs-language/asynchronous/4. async-await.md
LazarosZiskos b58872e
Update docs-language/asynchronous/4. async-await.md
LazarosZiskos b1b18c2
Update docs-language/asynchronous/4. async-await.md
LazarosZiskos 0f52476
Update docs-language/asynchronous/4. async-await.md
LazarosZiskos 3a6ef40
Update docs-language/asynchronous/3. promises.md
LazarosZiskos fc6a371
Update docs-language/asynchronous/3. promises.md
LazarosZiskos bcbbb8d
Update docs-language/asynchronous/3. promises.md
LazarosZiskos 765831f
Update docs-language/asynchronous/3. promises.md
LazarosZiskos 93742b1
Update docs-language/asynchronous/3. promises.md
LazarosZiskos 47d81a2
Update docs-language/asynchronous/4. async-await.md
LazarosZiskos 708b834
Update docs-language/asynchronous/3. promises.md
LazarosZiskos 2ca67ed
Update docs-language/asynchronous/3. promises.md
LazarosZiskos 82a56db
Update docs-language/asynchronous/4. async-await.md
LazarosZiskos 7949239
Update docs-language/asynchronous/4. async-await.md
LazarosZiskos 2b1420f
Update docs-language/asynchronous/4. async-await.md
LazarosZiskos 64c2a9f
Update docs-language/asynchronous/4. async-await.md
LazarosZiskos 84929da
Update docs-language/asynchronous/4. async-await.md
LazarosZiskos a461446
Update docs-language/asynchronous/4. async-await.md
LazarosZiskos a34c125
Update docs-language/asynchronous/4. async-await.md
LazarosZiskos f59f378
Update docs-language/asynchronous/4. async-await.md
LazarosZiskos 00db404
Update docs-language/asynchronous/4. async-await.md
LazarosZiskos 1693b37
Update docs-language/asynchronous/4. async-await.md
LazarosZiskos File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,163 @@ | ||
| # Promises | ||
|
|
||
| Όταν γράφουμε ασύγχρονο κώδικα στη JavaScript, μία μοντέρνα μεθόδος για να χειριστούμε αποτελέσματα που θα λάβουμε μελλοντικά (όπως απαντήσεις από έναν server), είναι μέσω της χρήσης των Promises. Τα Promises μας επιτρέπουν να οργανώνουμε αλυσιδωτές λειτουργίες και να διαχειριζόμαστε επιτυχίες και αποτυχίες σε ασύγχρονες διαδικασίες, αποφεύγοντας το γνωστό "Callback Hell" που αναφέραμε στην προηγούμενη ενότητα. | ||
|
|
||
| ## Δημιουργία ενός Promise | ||
|
|
||
| Ένα Promise δημιουργείται μέσω του constructor `promise`, ο οποίος δέχεται μια συνάρτηση με δύο παραμέτρους. Η συνάρτηση αυτή ονομάζεται executor (εκτελεστής) και εκτελείται αυτόματα μόλις δημιουργηθεί το Promise. | ||
|
|
||
| Τα δύο ορίσματα που δέχεται, `resolve` και `reject`, είναι callback functions και έχουν τις εξής λειτουργίες: | ||
|
|
||
| - resolve: Η διαδικασία επιτυγχάνει και μας επιστρέφεται η τελική τιμή. | ||
| - reject: Η διαδικασία αποτυγχάνει και μας επιστρέφεραι ένα error `object`, δηλαδή το exception value. | ||
|
|
||
| ```javascript | ||
| const myPromise = new Promise((resolve, reject) => { | ||
| const success = true; | ||
|
|
||
| if (success) { | ||
| resolve("Επιτυχία!"); | ||
| } else { | ||
| reject("Αποτυχία"); | ||
| } | ||
| }); | ||
| ``` | ||
| Στο παραπάνω παράδειγμα, η `arrow function` είναι η συνάρτηση executor. Η παράμετρος `resolve` καλείται καθώς η διαδικασία που θέλουμε να εκτελέσουμε στην executor function επιτυγχάνει. | ||
|
|
||
| ## Κατάσταση ενός Promise | ||
|
|
||
| Ένα Promise έχει τρείς δυνατές καταστάσεις: | ||
|
|
||
| | Κατάσταση | Περιγραφή | | ||
| |-----------|--------------------------------------------| | ||
| | `pending` | Το promise δεν έχει ακόμη επιλυθεί | | ||
| | `fulfilled` | Το promise επιλύθηκε με επιτυχία | | ||
| | `rejected` | Το promise απορρίφθηκε λόγω σφάλματος | | ||
|
|
||
| Μόλις φύγει από την κατάσταση `Pending`, το Promise "κλειδώνει και δεν αλλάζει ξανά κατάσταση. | ||
|
|
||
| ## Μέθοδοι then και catch | ||
|
|
||
| Για να χειριστούμε το αποτέλεσμα ενός Promise, χρησιμοποιούμε τις μεθόδους `.then()` και `.catch()`. | ||
|
|
||
| - H `then` καλείται όταν το Promise επιλυθεί επιτυχώς. | ||
| - Η `catch` καλείται όταν το Promise απορριφθεί λόγω σφάλματος. | ||
|
|
||
| ```javascript | ||
| let promise = new Promise((resolve, reject) => { | ||
| resolve("success"); | ||
| }); | ||
|
|
||
| myPromise | ||
| .then((message) => { | ||
| console.log("Μήνυμα": message); | ||
| }) | ||
| .catch((error) => { | ||
| console.error("Σφάλμα": error); | ||
| }); | ||
| ``` | ||
| - H `then` καλείται όταν το Promise επιλυθεί επιτυχώς. | ||
| - Η `catch` καλείται όταν το Promise απορριφθεί λόγω σφάλματος. | ||
|
|
||
| :::tip | ||
|
|
||
| Αν καλέσεις `.then()` ή `.catch()` πάνω σε ένα Promise που έχει *ήδη* επιλυθεί ή απορριφθεί, ο χειριστής θα εκτελεστεί άμεσα, χωρίς καθυστέρηση. Τα Promises είναι *μιας χρήσης* που σημαίνει ότι δεν μπορούν να "επαναληφθούν" ή να "ξαναπροσπαθήσουν". | ||
|
|
||
| ::: | ||
|
|
||
|
|
||
| ## Αλυσιδωτές Λειτουργίες (Chaining) | ||
|
|
||
| Ένα από τα χαρακτηριστικά των **Promises** είναι η δυνατότητα να δημιουργόυμε αλυσίδες ενεργειων. Για παράδειγμα: | ||
|
|
||
| ```javascript | ||
| fetch("https://jsonplaceholder.typicode.com/posts/1") | ||
| .then((response) => response.json()) | ||
| .then((data) => { | ||
| console.log("Δεδομένα:", data) | ||
| }); | ||
| .catch((error) => { | ||
| cosole.error("Σφάλμα στο fetch:", error); | ||
| }); | ||
| ``` | ||
| Κάθε `then` επιστρέφει ένα νέο Promise, επιτρέποντας συνεχή επεξεργασία δεδομένων. | ||
|
|
||
| ## Παραδείγματα | ||
|
|
||
| * Promise με καθυστέρηση | ||
|
|
||
| ```javascript | ||
| function delay(ms) { | ||
| return new Promise((resolve) => { | ||
| setTimeout(() => resolve(`Έγινε μετά από ${ms}ms`), ms); | ||
| }); | ||
| } | ||
|
|
||
| delay(1000).then((msg) => console.log(msg)); | ||
| ``` | ||
|
|
||
| * Χειρισμός Σφαλμάτων | ||
|
|
||
| ```javascript | ||
| function riskyOperation() { | ||
| return new Promise((resolve, reject) => { | ||
| const ok = Math.random() > 0.5; | ||
| ok ? resolve("Όλα καλά") : reject("Κάτι πήγε στραβά"); | ||
| }); | ||
| } | ||
|
|
||
| riskyOperation() | ||
| .then(console.log) | ||
| .catch(console.error); | ||
| ``` | ||
|
|
||
| ## Promise.all και Promise.race | ||
|
|
||
| Η Javascript παρέχει μερικές βοηθητικές στατικές μεθόδους για συνδιασμό πολλών **Promises**: | ||
|
|
||
| * `Promise.all` | ||
| Εκτελεί πολλά Promises και περιμένει να ολοκληρωθούν όλες. Παράδειγμα: | ||
|
|
||
| ```javascript | ||
| Promise.all([ | ||
| fetch("/data1.json"), | ||
| fetch("/data2.json") | ||
| ]) | ||
| .then(([res1, res2]) => Promise.all([res1.json(), res2.json()])) | ||
| .then(([data1, data2]) => { | ||
| console.log("Δεδομένα 1:", data1); | ||
| console.log("Δεδομένα 2:", data2); | ||
| }) | ||
| .catch(console.error); | ||
| ``` | ||
| Αν ένα αποτύχει, απορρίπτεται ολόκληρο το **Promise**. | ||
|
|
||
| * `Promise.race` | ||
| Επιστρέφει το αποτέλεσμα του πρώτου **Promise** που θα ολοκληρωθεί. | ||
| ```javascript | ||
| const fast = new Promise(res => setTimeout(() => res("Γρήγορη"), 500)); | ||
| const slow = new Promise(res => setTimeout(() => res("Αργή"), 1000)); | ||
|
|
||
| Promise.race([fast, slow]).then(console.log); // "Γρήγορη" | ||
| ``` | ||
|
|
||
| # Πλεονεκτήματα Promises | ||
|
|
||
| - Καθαρός κώδικας απο τα callbacks. | ||
| - Αποφυγή nested callbacks (callback hell). | ||
| - Εύκολος χειρισμός σφαλμάτων με `.catch()`. | ||
| - Συμβατότητα με `async/await`, για καθαρότερο κώδικα. | ||
|
|
||
| # Σύγκριση με άλλες μεθόδους | ||
|
|
||
| | Μέθοδος | Πλεονεκτήματα | Μειονεκτήματα | | ||
| |---------------|--------------------------------------------|------------------------------------------------| | ||
| | Callbacks | Απλή και ευέλικτη | Δύσκολος έλεγχος ροής, callback hell | | ||
| | Promises | Καλύτερη ροή, ευκολότερο debugging | Περίπλοκες αλυσίδες μπορεί να μπερδέψουν | | ||
| | Async/Await | Συγχρονική μορφή, πιο καθαρός χειρισμός | Απαιτεί κατανόηση των Promises | | ||
|
|
||
|
|
||
| # Συμπέρασμα | ||
|
|
||
| Τα Promises είναι βασικά εργαλεία για τη συγγραφή ασύγχρονου κώδικα στη Javascript. Διευκολύνουν τον έλεγχο ροής, τον χειρσμό σφαλμάτων και συνεργάζονται άψογα με το `async/await`. Κατανοώντας τα Promises, αποκτάς τον έλεγχο των ασύγχρονων λειτουργιών της Javascript με καθαρό, επεκτάσιμο τροπο. | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,160 @@ | ||
| # Async/Await | ||
|
|
||
| Το async/await χρησιμοποιείται για να απλοποιήσει τη διαχείριση ασύγχρονων λειτουργιών που βασίζονται σε Promises. Επιτρέπει τη συγγραφή ασύγχρονου κώδικα με τρόπο που μοιάζει με συγχρονική εκτέλεση, καθιστώντας τον πιο ευανάγνωστο και ευκολότερο στη συντήρηση, ιδιαίτερα σε σύνθετες ροές. | ||
|
|
||
| Η λέξη κλειδί `async` χρησιμοποιείται μπροστά από μία συνάρτηση ή μέθοδο, καθιστώντας την ασύγχρονη. Όταν καλείται, επιστρέφει άμεσα ένα promise, το οποίο εκπληρώνεται μόλις η συνάρτηση επιστρέψει μια τιμή ή απορρίπτεται αν προκύψει εξαίρεση κατά την εκτέλεση. | ||
|
|
||
| Μέσα σε μια τέτοια συνάρτηση, μπορεί να χρησιμοποιηθεί η λέξη κλειδί 'await' για να «παγώσει» προσωρινά την εκτέλεση της μέχρι να ολοκληρωθεί το αντίστοιχο promise. Αν αυτό αποτύχει, ένα exception θα συμβεί στο σημείο του await, επιτρέποντας έτσι τη διαχείριση σφαλμάτων. | ||
|
|
||
| Ας δούμε κάποια παραδείγματα: | ||
|
|
||
| ```javascript | ||
| async function fetchData() { | ||
| const response = await fetch("https://jsonplaceholder.typicode.com/posts/1"); | ||
| const data = await response.json(); | ||
| console.log(data); | ||
| } | ||
| fetchData(); | ||
|
|
||
| // { "userId": 1, | ||
| // "id": 1, | ||
| // "title": "....", | ||
| // "body:" "..." } | ||
| ``` | ||
|
|
||
| Σε αυτό το παράδειγμα, η ασύγχρονη συνάρτηση `fetchData` περιμένει το αποτέλεσμα της εντολής 'fetch' και το μετατρέπει σε JSON πριν το εκτυπώσει. | ||
|
|
||
| ```javascript | ||
| async function myFunction() { | ||
| try { | ||
| const result = await someAsyncFunction(); | ||
| consolge.log(result); | ||
| } | ||
| catch (error) { | ||
| console.error("Σφάλμα", error.message); | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| Το παραπάνω παράδειγμα δείχνει τη χρήση της ασύγχρονης σύνταξης async/await σε συνδυασμό με τη δομή try/catch για διαχείριση σφαλμάτων. Η myFunction είναι μια ασύγχρονη συνάρτηση που περιμένει το αποτέλεσμα της someAsyncFunction() χρησιμοποιώντας το await. Αν το Promise επιλυθεί επιτυχώς, το αποτέλεσμα αναγράφεται στην κονσόλα. Αν προκύψει σφάλμα κατά την εκτέλεση της ασύγχρονης λειτουργίας, το exception εντοπίζεται στο catch και εμφανίζεται αντίστοιχο μήνυμα σφάλματος. Αυτή η προσέγγιση κάνει τη ροή του κώδικα πιο καθαρή και ευανάγνωστη, σε σύγκριση με τη χρήση 'then()' και 'catch()'. | ||
|
|
||
| ## Χειρισμός Σφαλμάτων με try/catch | ||
|
|
||
| Ο χειρισμός σφαλμάτων σε `async` συναρτήσεις γίνεται μεσω της χρήσης της δομής `try/catch`, όπως είδαμε στο προηγούμενο παράδειγμα. Αυτό μας δίνει τον έλεγχο σε κάθε πιθανό σφάλμα που μπορεί να προκύψει κατά την αναμονή ενός Promise. | ||
|
|
||
| ```javascript | ||
| async function fetchData() { | ||
| try { | ||
| const response = await fetch('https://api.example.com/data'); | ||
| const data = await response.json(); | ||
| console.log(data); | ||
| } catch (error) { | ||
| console.error("Σφάλμα κατά τη λήψη δεδομένων:", error); | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| H `try` "περιμένει" το αποτέλεσμα της `fetch` και η `catch` πιάνει οποιοδήποτε σφάλμα, είτε από το δίκτυο είτε κατά την επεξεργασία των δεδομένων. | ||
|
|
||
| ## Συχνές Χρήσεις | ||
|
|
||
| Η σύνταξη async/await χρησιμοποιείται κυρίως σε: | ||
|
|
||
| - Αιτήματα σε APIs | ||
| ```javascript | ||
| sync function fetchUser() { | ||
| try { | ||
| const response = await fetch('https://jsonplaceholder.typicode.com/users/1'); | ||
| const user = await response.json(); | ||
| console.log('Χρήστης:', user.name); | ||
| } catch (error) { | ||
| console.error('Σφάλμα στο fetch:', error.message); | ||
| } | ||
| } | ||
|
|
||
| fetchUser(); | ||
| ``` | ||
| Χρησιμοποιούμε το λεκτικό `await` για να περιμένουμε την απάντηση ενός API και στη συνέχεια να μετατρέψουμε τα δεδομένα σε JSON. | ||
|
|
||
| - Ανάγνωση αρχείων σε Node.js | ||
| ```javascript | ||
| const fs = require('fs/promise'); | ||
|
|
||
| async function readFileContent() { | ||
| try { | ||
| const content = await fs.readFile('example.txt', 'utf8'); | ||
| console.log('Περιεχόμενο:', content); | ||
| } catch(error) { | ||
| console.error("Σφάλμα ανάγνωσης αρχείου:", error); | ||
| } | ||
| } | ||
| readFileContent(); | ||
| ``` | ||
| Διαβάζουμε ένα αρχείο τοπικά μέσω `fs.promises.readFile`, χωρίς `.then()` ή εμφώλευση. | ||
|
|
||
| - Διαδοχικές ασύγχρονες λειτουργίες με εξαρτήσεις | ||
| ```javascript | ||
| async function loadUserData() { | ||
| try { | ||
| const user = await fetchUser(); // Βήμα 1 | ||
| const posts = await fetchPosts(user.id); // Βήμα 2 | ||
| const comments = await fetchComments(posts[0].id); // Βήμα 3 | ||
|
|
||
| console.log("Σχόλια στην πρώτη ανάρτηση:", comments); | ||
| } catch (error) { | ||
| console.error("Σφάλμα κατά τη φόρτωση δεδομένων:", error.message) | ||
| } | ||
| } | ||
|
|
||
| // Dummy async functions | ||
| async function fetchUser() { | ||
| return { id: 1, name: 'Νίκος' }; | ||
| } | ||
| async function fetchPosts(userId) { | ||
| return [{ id: 101, title: 'Πρώτη Ανάρτηση' }]; | ||
| } | ||
| async function fetchComments(postId) { | ||
| return ['Πολύ καλό άρθρο!', 'Ενδιαφέρον.']; | ||
| } | ||
|
|
||
| loadUserData(); | ||
| ``` | ||
| Το παραπάνω παράδειγμα δείχνει πώς μπορούμε να εκτελέσουμε διαδοχικές ασύγχρονες λειτουργίες χρησιμοποιώντας τη σύνταξη async/await. Αρχικά γίνεται ανάκτηση ενός χρήστη, στη συνέχεια φορτώνονται οι αναρτήσεις του και τέλος τα σχόλια της πρώτης ανάρτησης. Όλα αυτά περικλείονται σε δομή try/catch, ώστε να εντοπίζονται και να διαχειρίζονται τυχόν σφάλματα κατά τη διάρκεια της διαδικασίας. Κάθε βήμα εξαρτάται από το προηγούμενο και χωρίς την σύνταξη async/await αυτό θα γινόταν πολύπλοκο με εμφωλευμένα `.then()`. | ||
|
|
||
| - Αποφυγή `.then()` chaining και εμφωλευμένων callbacks | ||
| ```javascript | ||
| async function loadProfile() { | ||
| try { | ||
| const user = await getUser(); | ||
| const settings = await getSettings(user.id); | ||
| console.log('Ρυθμίσεις για:', user.name, settings); | ||
| } catch (error) { | ||
| console.error('Σφάλμα:', error.message); | ||
| } | ||
| } | ||
|
|
||
| // Mock async functions | ||
| const getUser = async () => ({ id: 42, name: 'Μαρία' }); | ||
| const getSettings = async (userId) => ({ theme: 'dark', language: 'el' }); | ||
|
|
||
| loadProfile(); | ||
| ``` | ||
| Αντί για `getUser().then().then()...,` χρησιμοποιούμε await για να γράψουμε τον κώδικα σε "γραμμική" μορφή. | ||
|
|
||
| ## Πλεονεκτήματα της async/await | ||
| - Βελτιωμένη Αναγνωσιμότητα: Ο κώδικας είναι πιο ευανάγνωστος και μοιάζει συγχρονικός. | ||
| - Εύκολος Χειρισμός Σφαλμάτων: Η χρήση `try/catch` κάνει τον χειρισμό σφαλμάτων πολύ πιο απλό. | ||
| - Αποφυγή Callback Hell: Δεν χρειάζονται εμφωλευμένα callbacks ούτε μακροσκελείς αλυσίδες `.then()`. | ||
| - Καλύτερο Debugging: Ο εντοπισμός σφαλμάτων είναι πιο απλός, καθώς η ροή θυμίζει συγχρονικό κώδικα. | ||
|
|
||
| ## 5. Σύγκριση με άλλες προσεγγίσεις | ||
|
|
||
| | Προσέγγιση | Πλεονεκτήματα | Μειονεκτήματα | | ||
| |----------------|--------------------------------------------------------|----------------------------------------------------------| | ||
| | **Callbacks** | Απλή υλοποίηση, παλιότερη υποστήριξη | Callback hell, δύσκολος έλεγχος σφαλμάτων | | ||
| | **Promises** | Αλυσιδωτές λειτουργίες, καλύτερη από τα callbacks | Ακόμη δύσκολος χειρισμός σε πολύπλοκες ροές | | ||
| | **Async/Await**| Καθαρός και ευθύγραμμος κώδικας, χρήση try/catch | Απαιτεί κατανόηση των Promises και ES2017+ περιβάλλον | | ||
|
|
||
|
|
||
|
|
||
|
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.