Javascript 如何捕获异步非承诺错误?(对该特定错误作出反应)

Javascript 如何捕获异步非承诺错误?(对该特定错误作出反应),javascript,typescript,async-await,es6-promise,ecmascript-2017,Javascript,Typescript,Async Await,Es6 Promise,Ecmascript 2017,我知道有答案,但我没有找到一个具体的答案,我的实际问题 目前我经常使用以下模式: class A { getLocation() { return Promise.reject(2222222) } async a() { try { var loc = await this.getLocation(); alert(loc)

我知道有答案,但我没有找到一个具体的答案,我的实际问题

目前我经常使用以下模式:

 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();
  • 结果:“第二个陷阱”
事件,如果我在
getLocation
中抛出错误:

  getLocation()
     {
         throw Error("ffffff")
     }
-我得到了同样的结果——这没关系

那么问题出在哪里呢?

正如您所知,异步抛出的非承诺错误是另一种错误:

因此:

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

关于我想要捕捉错误的事实,是否有更好的模式来捕捉错误

当然我能做到:

window.onerror = function () { alert(4)}
但这将不符合
.catch(…)
catch(){}
的流程,我将无法针对导致错误的特定操作执行操作

完全披露:

没有真实的生活场景。学习目的。

错误应该在发生的地方被发现

此类代码不正确,应就地修复:

  getLocation() //bad code from a third party code
  { 
      return new Promise((v, x) => setTimeout(() =>
      {
          throw Error("ffffff")
      }, 100))
  }
如果这是第三方代码,则可以对其进行分叉或修补

正如问题已经提到的,异常可以通过全局跟踪。这应该只用于通知开发人员存在的错误,而不是以正常方式处理它们


事件可用于相同目的,以通知承诺中未处理的拒绝。它将无法处理上面截取的错误,因为它被抛出到
setTimeout
回调中,并且不会导致承诺拒绝。

错误应该在发生的地方捕获

此类代码不正确,应就地修复:

  getLocation() //bad code from a third party code
  { 
      return new Promise((v, x) => setTimeout(() =>
      {
          throw Error("ffffff")
      }, 100))
  }
如果这是第三方代码,则可以对其进行分叉或修补

正如问题已经提到的,异常可以通过全局跟踪。这应该只用于通知开发人员存在的错误,而不是以正常方式处理它们


事件可用于相同目的,以通知承诺中未处理的拒绝。它将无法处理上面截取的错误,因为它在
setTimeout
回调中抛出,不会导致承诺被拒绝。

我猜基本用法如下:

A类{
获取位置(x){
返回新承诺((解析、拒绝)=>setTimeout(()=>{
//大量异步代码
试一试{
//模拟意外异常
如果(x==2){
抛出(“代码错误”);
}
if(x){
决心(“成功”);
}否则{
拒绝(“有条件拒绝”);
}
}捕获(ex){
拒绝(ex);
}
}, 1000));
}
异步a(x){
等待这个.getLocation(x).然后((loc)=>console.info(loc)).catch((e)=>console.error(e));
}
}
设o=新的A();
o、 a(2);
o、 a(0);

o、 a(1)我猜基本用法如下:

A类{
获取位置(x){
返回新承诺((解析、拒绝)=>setTimeout(()=>{
//大量异步代码
试一试{
//模拟意外异常
如果(x==2){
抛出(“代码错误”);
}
if(x){
决心(“成功”);
}否则{
拒绝(“有条件拒绝”);
}
}捕获(ex){
拒绝(ex);
}
}, 1000));
}
异步a(x){
等待这个.getLocation(x).然后((loc)=>console.info(loc)).catch((e)=>console.error(e));
}
}
设o=新的A();
o、 a(2);
o、 a(0);
o、 a(1)
非承诺异步抛出的错误是另一种错误

对。必须不惜一切代价避免这种情况。因此,从不将业务代码(包括诸如属性访问之类的琐碎事情)放入异步非承诺回调中。它可以扔!显然,
JSON.parse
可能会失败,当“object”为
null
未定义
或涉及getter时,属性访问可能会抛出,或者当假定为数组的对象没有
长度时,循环可能会失败

唯一允许作为异步非承诺回调的是
resolve
reject
,和
(err,res)=>{if(err)reject(err);else resolve(res);}
(对于具有多个参数的古怪API,可能是可变版本)

因此,将错误代码重写为

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

当第三方代码让他们修复它时,对你的修复提出上游合并请求,或者如果那些不起作用,就放弃该方

有没有更好的模式来捕捉这一点

嗯,(在节点中)应该解决异步(未捕获)异常的非局部性问题,但是。也许有一天,更好的母语支持将取代它们

非承诺异步抛出的错误是另一种错误

对。必须不惜一切代价避免这种情况。因此,从不将业务代码(包括诸如属性访问之类的琐碎事情)放入异步非承诺回调中。它可以扔!显然,
JSON.parse
可能会失败,当“object”为
null
未定义
或涉及getter时,属性访问可能会抛出,或者当假定为数组的对象没有
长度时,循环可能会失败

唯一允许作为异步非承诺回调的是
resolve
reject
,和
(err,res)=>{if(err)reject(err);else resolve(res);}
(对于具有多个参数的古怪API,可能是可变版本)

因此,将错误代码重写为

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

当第三方代码让他们修复它时,对你的修复提出上游合并请求,或者如果那些不起作用,就放弃该方

有没有更好的模式来捕捉这一点

那么,(在节点中)应该解决这个问题