0

Ich weiß, dass es Antworten gibt, aber ich habe keine spezifische Antwort auf meine eigentliche Frage gefunden.Wie kann ich asynchrone nicht versprochene Fehler abfangen? (Reagieren Sie auf diesen spezifischen Fehler)

Derzeit use ich folgendes Muster viel:

class A 
{ 
    getLocation() 
    { 
     return Promise.reject(2222222) 
    } 
    async a() 
    { 
     try 
     { 
      var loc = await this.getLocation(); 
      alert(loc) 
     } 
     catch (e) 
     { 
      alert("catch 2") 
     } 
    } 
} 
new A().a(); 
  • Ergebnis: "Fang 2"

Ereignis Wenn ich einen Fehler in getLocation werfen:

getLocation() 
    { 
     throw Error("ffffff") 
    } 

- Ich bekomme das gleiche Ergebnis - was in Ordnung ist.

Also wo ist das Problem?

Nun, wie Sie wissen, ein Fehler, der asynchronously-non-promised geworfen wird, ist ein anderes Tier:

So this code won't be catched überhaupt:

getLocation() //bad code from a third party code , third party code 
    { 
     return new Promise((v, x) => setTimeout(() => 
     { 
      throw Error("ffffff") 
     }, 100)) 
    } 

Frage:

die Tatsache Bezug, dass ich Fehler suchen wollen - gibt es ein besseres Muster dafür?

Sicher kann ich tun:

window.onerror = function() { alert(4)} 

Aber das wäre nicht in Ordnung wie die Strömung von .catch(...) oder catch(){}, und ich werde nicht in der Lage sein, Maßnahmen zu tun in Bezug auf dass spezifische Aktion, die Fehler verursacht .

Vollständige Offenlegung:
Kein wirkliches Leben Szenario. Lernziel.

Antwort

2

ein Fehler, der asynchron nicht versprochen geworfen wird, ist ein anderes Tier

Ja. Und es muss um jeden Preis vermieden werden. Daher nie Business-Code (einschließlich triviale Dinge wie Eigentum Zugriffe) in asynchronen nicht-Versprechen Callbacks. Es könnte werfen! Es sollte offensichtlich sein, dass JSON.parse kann fehlschlagen, dass eine Eigenschaft zugreifen kann, wenn das "Objekt" ist null oder undefined oder ein Getter beteiligt ist, oder dass eine Schleife kann fehlschlagen, wenn die Sache, die ein Array sein sollte, keine .length.

Die einzigen Dinge, die als asynchrone nicht-Versprechen Rückrufe sind nicht zulässig sind resolve, reject und (err, res) => { if (err) reject(err); else resolve(res); } (und vielleicht eine variadische Version für seltsame APIs mit mehreren Argumenten).

So schreiben die schlechten Code zu

async getLocation() { 
    await new Promise(resolve => setTimeout(resolve, 100)); 
    throw Error("ffffff"); 
} 

oder

getLocation() { 
    return new Promise(resolve => setTimeout(resolve, 100)).then(res => { 
     throw Error("ffffff"); 
    }); 
} 

und wenn es Code von Drittanbietern ist machen sie es beheben, machen einen vorgeschalteten merge Anforderung Ihrer fix, oder wenn diejenigen, don Arbeit nicht aufgeben.

Gibt es ein besseres Muster für die Erfassung?

Nun, domains (in Knoten) sollte dieses Problem der Nichtlokalität von asynchronen (abgefangene) Ausnahmen lösen, aber they didn't work out. Vielleicht wird eines Tages zones mit besserer Unterstützung für die Muttersprache sie ersetzen.

0

Die Fehler sollten dort eingefangen werden, wo sie auftreten.

Diese Art von Code Code ist falsch und sollte an Ort und Stelle festgelegt werden:

getLocation() //bad code from a third party code 
    { 
     return new Promise((v, x) => setTimeout(() => 
     { 
      throw Error("ffffff") 
     }, 100)) 
    } 

Wenn dieser Code von Drittanbietern ist, kann es gegabelt oder gepatcht werden.

Ausnahmen können global von onerror verfolgt werden, wie die Frage bereits erwähnt. Dies sollte nur verwendet werden, um einen Entwickler über bestehende Fehler zu benachrichtigen, nicht um sie auf normale Weise zu behandeln.

unhandledrejection Ereignis kann für den gleichen Zweck verwendet werden, um über unbehandelte Ablehnungen in Versprechen zu informieren. Es wird nicht in der Lage sein, den Fehler in dem oben abgeschnittenen zu behandeln, da es innerhalb setTimeout Callbacks ausgelöst wird und zu Verheißungsverweigerung nicht führt.

0

Ich denke, die grundlegende Verwendung so sein würde:

class A { 
 
    getLocation(x) { 
 
    return new Promise((resolve, reject) => setTimeout(() => { 
 
     // a lot of async code 
 
     try { 
 
     //simulate unexpected exception  
 
     if (x === 2) { 
 
      throw ("code error"); 
 
     } 
 
     if (x) { 
 
      resolve('success'); 
 
     } else { 
 
      reject('conditional rejection'); 
 
     } 
 
     } catch (ex) { 
 
     reject(ex); 
 
     } 
 
    }, 1000)); 
 
    } 
 
    async a(x) { 
 
    await this.getLocation(x).then((loc) => console.info(loc)).catch((e) => console.error(e)); 
 
    } 
 
} 
 
let o = new A(); 
 
o.a(2); 
 
o.a(0); 
 
o.a(1);

Die Ablehnung des Promise ist nicht unbedingt ein Code Exception sowie der Code Exception sollte nicht unbedingt lösen eine Promise Ablehnung.

Verwandte Themen