2017-10-17 4 views
-1

Ich habe eine Node.js App. Diese App hat eine Schaltfläche, die einen Prozess startet. Die Schritte in diesem Prozess geben Versprechen zurück. Ich versuche diese Versprechen zusammen zu ketten. Aus irgendeinem Grund erhalte ich eine UnhandledPromiseRejectionWarning. In meinen Augen habe ich das jedoch richtig eingerichtet. Mein Code sieht wie folgt aus:Node.js: Unhandled Versprechen Ablehnung - UnhandledPromiseRejectionWarning

var myButton = document.getElementById('myButton'); 
if (myButton) { 
    console.log('here'); 
    myButton.addEventListener('click', executeAction('0')); 
} 

function executeAction(input) {  
    let param1 = 'A'; 
    let promise = new Promise(function(resolve, reject) { 
    try { 
     executeStep1() 
     .then(result => executeStep2(param1, result, input)) 
     .then(result => function(result) { 
      console.log('All done'); 
      resolve(result); 
     }) 
     .catch(err => reject(err)) 
     ; 
    } catch (ex) { 
     reject(ex); 
    } 
    }); 
    return promise;  
} 

function executeStep1() { 
    let promise = new Promise(function(resolve, reject) {   
    try { 
     setTimeout(function() { 
     resolve('[something]'); 
     }, 3000); 
    } catch (ex) { 
     reject(); 
    } 
    }); 
    return promise; 
} 

function executeStep2(p1, p2, p3) { 
    let promise = new Promise(function(resolve, reject) {   
    try { 
     setTimeout(function() { 
     console.log('step 2 has executed'); 
     resolve('awesome!') 
     }, 3000); 
    } catch (ex) { 
     reject(ex); 
    } 
    }); 
    return promise; 
} 

ich bestätigt habe, dass die executeStep2 Funktion bis zur Fertigstellung läuft. Ich basiere dies in der Tatsache, dass ich "Schritt 2 hat ausgeführt" im Konsolenfenster sehen kann. Zu meiner Überraschung sehe ich jedoch nie "Alles fertig" im Konsolenfenster. Stattdessen sehe ich das oben erwähnte UnhandledPromiseRejectionWarning. Ich verstehe zwei Dinge über dieses Ergebnis nicht:

  1. Warum sehe ich nicht "Alles fertig" in der Konsole? Sollte diese Funktion nicht ausgeführt werden, nachdem executeStep2 aufgelöst wurde?
  2. Woher kommt die Ablehnung? Ich sehe nichts, was das ablehnt.

Vielen Dank für Ihre Hilfe!

+0

Remove 'Funktion (Ergebnis)' in der zweiten 'then'. Sie verwenden dort bereits die Pfeilfunktionssyntax, um die Funktion zu deklarieren. –

+0

Vermeide die ['Promise'-Konstruktor-Antipattern] (https://stackoverflow.com/q/23803743/1048572?Was-ist-die-Promose-Konstruktion-antipattern-und-wie-zum- Vermeiden-) trotzdem! Btw, du brauchst nie 'try {...} catch (err) {reject (err)}' in einem 'neuen Promise'-Callback, der Konstruktor macht das automatisch. – Bergi

+0

Was genau ist das "etwas" in deinem "executeStep2", ist das eigentlich ein Ausdruck, der eine Ausnahme auslösen könnte? – Bergi

Antwort

0
executeStep1() 
    .then(result => executeStep2(param1, result, input)) 
    .then(result => { // no function(result) here 
     console.log('All done'); 
     resolve(result); 
    }) 
    .catch(err => reject(err)) 
    ; 
+1

Dies ist näher. Es hängt nicht mehr, wenn ich es laufe. Ich erhalte jedoch weiterhin den Fehler 'UnhandledPromiseRejectionWarning'. –

0

Der Fehler wird generiert aus, wenn Sie die Funktion aufrufen (n), die Versprechen verwendet:

myButton.addEventListener('click', executeAction('0')); 

Sie müssen Ablehnungen fangen dort auch.

myButton.addEventListener('click', executeAction('0') 
    .catch((error) => console.log('ERROR', error)); 

Die Ablehnungen sind in den Funktionen gefangen, aber nicht in dem äußeren Umfang, weil executeAction('0') ein Versprechen gibt, oder es würde aber Sie es als nicht-Asynchron-Funktion verwenden, so dass sie ein Versprechen zu schaffen und dann Rückkehr ein ausstehendes Versprechen, ohne darauf zu warten, dass es gelöst wird. Das sieht aus, was die Ablehnung verursacht, und es wird auch nicht aus dem oben genannten Grund behandelt.

Dieses es beheben:

function executeAction(input) {  
    let param1 = 'A'; 
    return new Promise(function(resolve, reject) { 
    try { 
     executeStep1() 
     .then(result => executeStep2(param1, result, input)) 
     .then(result => function(result) { 
      console.log('All done'); 
      resolve(result); 
     }) 
     .catch(err => reject(err)) 
     ; 
    } catch (ex) { 
     reject(ex); 
    } 
    }); 
} 

Sie in async aussehen sollte/abzuwarten. Es kann diesen Code deutlich aufräumen.

async function getSomething() { 
 
     try { 
 
     // throw 'Test error detected.' 
 
     return 'test' 
 
     } 
 
     catch (e) { 
 
     throw e 
 
     } 
 
    } 
 
    
 
    async function testing() { 
 
     try { 
 
     const sample = await getSomething() 
 
     return sample 
 
     } catch (e) { 
 
     throw e 
 
     } 
 
    } 
 
    
 
    testing() 
 
     .then((data) => console.log(data)) 
 
     .catch((err) => console.log(err))

Führen Sie dieses Beispiel oben und dann Kommentar- der Wurf. Verwenden Sie dieses Muster für den maximalen Gewinn. Ausnahmen sollten auf die Oberflächenniveau geworfen werden, wo die Funktionen aufgerufen, angezeigt, verwendet, gerendert usw. werden. Funktionen sollten einfach den Fehler auswerfen.

Auf diese Weise können Sie die Fehlerbehandlung Middleware, Funktionen höherer Ordnung verwenden, Hörer, Logging etc.

Verwandte Themen