Αποτροπή της «Ασύλληπτος (στην υπόσχεση)» προειδοποίηση. Πώς να αποφύγετε των μπλοκ «αλιευμάτων»; ES6 υπόσχεται vs υποσχέσεις Q

ψήφοι
0

Η ερώτησή μου αποτελείται από δύο μέρη:

Μέρος 1

Σύμφωνα με το πρότυπο ES6 Promiseβλέπω ότι αναγκάζονται να χρησιμοποιούν catchμπλοκ παντού, αλλά μοιάζει με copy / paste και φαίνεται παράξενο.

Παράδειγμα:

Έχω κάποια τάξη που κάνει αίτηση για backend (ας το ονομάσουμε APIκατηγορία).

Και έχω μερικές απαιτήσεις για την APIτάξη με τη χρήση:

1) Θα πρέπει να κάνετε αιτήσεις σε διάφορα μέρη της αίτησής μου με ενιαίο επεξεργασίας λάθη αίτημα:

// somewhere...
api.getUser().then(... some logic ...);

// somewhere in another module and in another part of app...
api.getUser().then(... some another logic...); 

2) Θέλω τόσο «τότε» μπλοκ θα μπορούσε να λειτουργήσει μόνο όταν καταφέρει «getUsers».

3) Δεν θέλω να γράψω catchμπλοκ παντού μπορώ να χρησιμοποιήσωapi.getUsers()

api.getUser()
// I don't want following
.catch(e => {
    showAlert('request failed');
})

Έτσι είμαι προσπαθεί να εφαρμόσει ενιαίο επεξεργασίας σφάλματος στο εσωτερικό της κατηγορίας για όλους «τα αιτήματα των χρηστών»

class API {
    getUser() {
        let promise = makeRequestToGetUser();
        promise.catch(e => {
            showAlert('request failed');
        });
        return promise;
    }
}

... αλλά αν το αίτημα δεν έχω ακόμα αναγκασμένοι να χρησιμοποιούν catchμπλοκ

api.getUser()
    .then(... some logic...)
    .catch(() => {}) // <- I forced to write it to avoid of “Uncaught (in promise)” warning

... αλλιώς θα πάρω «Ασύλληπτος (στην υπόσχεση)» προειδοποίηση στην κονσόλα. Γι 'αυτό και δεν ξέρω τον τρόπο για το πώς να αποφευχθεί των .catchμπλοκ παντού μπορώ να χρησιμοποιήσω apiπαράδειγμα.

Φαίνεται αυτό προέρχεται από τη ρίψη σφάλμα σε τέτοιες κωδικό:

// This cause Uncaught error
Promise.reject('some value').then(() => {});

Μπορεί να μπορείτε να πείτε «μόλις επιστρέψει στην τάξη σας“catched”υπόσχεση».

class API {
    getUser() {
        return makeRequestToGetUser().catch(e => {
            showAlert('request failed');
            return ... 
        });
    }
}

... αλλά αυτό έρχονται σε αντίθεση με μου # 2 απαίτηση.

Δείτε αυτό το demo: https://stackblitz.com/edit/js-xqwiq1?file=index.js

Έτσι 1ο ερώτησή μου είναι πώς να εφαρμόσουν περιγράφεται λογική, χωρίς να γράψετε catchμπλοκ παντού μπορώ να χρησιμοποιήσω apiκλήση;

Μέρος 2ο

Έλεγξα αν η ίδια APIεφαρμογή τάξη με Qτη βιβλιοθήκη θα πάρει το ίδιο αποτέλεσμα και ήταν έκπληξη , γιατί δεν παίρνω “Uncaught (in promise)” warning. BTW είναι πιο αναμενόμενο συμπεριφορά από τη συμπεριφορά των ιθαγενών υποσχέσεις ES6.

Δείτε αυτό το demo https://stackblitz.com/edit/js-g6efg5

Σε αυτή τη σελίδα https://promisesaplus.com/implementations διαπίστωσα ότι Qη βιβλιοθήκη είναι η εφαρμογή των υποσχέσεων / A + spec. Αλλά γιατί πρέπει διαφορετική συμπεριφορά; Μήπως υπόσχεση ES6 σέβεται Υποσχέσεις / A + spec;

Μπορεί κανείς να εξηγήσει γιατί οι βιβλιοθήκες έχει διαφορετική συμπεριφορά, η οποία το ένα είναι σωστό, και πώς να εφαρμόσουν προαναφερθείσα λογική σε περίπτωση «ES6 υπόσχεται εφαρμογή» είναι σωστή;

Δημοσιεύθηκε 27/11/2018 στις 17:34
πηγή χρήστη
Σε άλλες γλώσσες...                            


1 απαντήσεις

ψήφοι
1

Βλέπω ότι αναγκάζονται να χρησιμοποιούν μπλοκ των αλιευμάτων παντού

Όχι, δεν χρειάζεται να το κάνουμε αυτό. Αντ 'αυτού, να επιστρέψει την υπόσχεση που δημιουργήθηκε από thenτον καλούντα (και καλών αυτού του καλούντος, και ...). Χειριστείτε τα λάθη στο ανώτατο επίπεδο διαθέσιμη (για παράδειγμα, το πρόγραμμα χειρισμού συμβάντων που άρχισε την ακολουθία κλήσης).

Αν αυτό είναι ακόμα πάρα πολλά catchγια σένα, μπορείτε να συνδέσετε την unhandledrejectionεκδήλωση και την πρόληψη προεπιλογή της:

window.addEventListener('unhandledrejection', event => {
    event.preventDefault();
    // You can use `event.reason` here for the rejection reason, and
    // `event.promise` for the promise that was rejected
    console.log(`Suppressed the rejection '${event.reason.message}'`);
});

Promise.reject(new Error("Something went wrong"));

Το πρόγραμμα περιήγησης θα προκαλέσει αυτό το γεγονός πριν από την αναφορά της απρόσμενο απόρριψη στην κονσόλα.

Node.js υποστηρίζει αυτό, καθώς, στο processαντικείμενο:

process.on('unhandledRejection', error => {
  // `error` is the rejection reason
});

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

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

Σίγουρα ο επισκέπτης του getUserπρέπει να γνωρίζει ότι απέτυχε; Θέλω να πω, αν η απάντηση σε αυτό είναι πραγματικά «όχι, δεν το κάνουν», τότε η περίπτωση είναι ο τρόπος να πάει, αλλά πραγματικά ο κώδικας χρήση apiθα πρέπει να μοιάζει κάπως έτσι:

function useTheAPI() {
    return getUser()
        .then(user => {
            // Do something with user
        });
}

(ή το asyncισοδύναμο) έτσι ώστε ο κωδικός κλήσης useTheAPIγνωρίζει ότι παρουσιάστηκε ένα σφάλμα? και πάλι, μόνο η υψηλού επιπέδου πρέπει να χειριστεί πραγματικά το σφάλμα.

Μπορεί κανείς να εξηγήσει γιατί οι βιβλιοθήκες έχει διαφορετική συμπεριφορά, η οποία το ένα είναι σωστό, και πώς να εφαρμόσουν προαναφερθείσα λογική σε περίπτωση «ES6 υπόσχεται εφαρμογή» είναι σωστή;

Και οι δύο είναι σωστές. Αναφορά unhandled εξαιρέσεις εξ ολοκλήρου στην userland (όπου ζουν οι βιβλιοθήκες) είναι δύσκολο να αδύνατο να γίνει έτσι ώστε να μην υπάρχουν ψευδώς θετικά. Οι μηχανές Javascript για να το κάνετε ως μέρος της συλλογής απορριμμάτων τους (π.χ. αν μη τι έχει σχέση με την υπόσχεση πια, και απορρίφθηκε, και τίποτα δεν αντιμετωπίζεται η απόρριψη, το θέμα της προειδοποίησης).

Απαντήθηκε 27/11/2018 στις 17:45
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more