如何使用async / await构造try / catch?

时间:2019-05-13 20:41:02

标签: javascript ecmascript-6 async-await

我有以下代码,简化为省去了不必要的内容:

try {
  const response = await axios.put(url, {});
  if ( response.status === 200 ) {
    MicroService.action(data);
  }
} catch ( error ) {
  // user is not signed in, so send to create-account/sign-in
  if (error.status === 401) {
    MicroService.otherAction(data);
  } else {
    console.error(`The server returned an unexpected ${error.status} error upon attempting to hit ${url}`);
  }
}

问题在于catch子句还捕获第四行MicroService.action(data)中发生的任何错误。我希望在第2行的axios调用中捕获错误,没有其他错误应该被忽略。

但是,如果我拿起MicroService.action(data)并将其移至catch之后,即使try失败了也会发生,这是错误的。仅在try成功的情况下才会发生。

我可以在try子句中设置一个变量,例如if (response.status === 200) let success = true;,然后在catch子句之后检查该变量。但这对于除了最简单的情况之外的任何事情来说都是凌乱而笨拙的。

有更好的方法吗?

3 个答案:

答案 0 :(得分:2)

通过覆盖vexing exceptions回调来避免validateStatus。如果401状态码是预期的结果,则将其视为正常结果,并允许其他意外状态码正常抛出:

const response = await axios.put(url, {}, {
  validateStatus (status) {
    return [200, 401].includes(status);
  }
});

switch (response.status) {
case 200:
  MicroService.action(data);
  break;
case 401:
  MicroService.otherAction(data);
  break;
}

如果您不希望任何状态码引发错误,请在default语句中添加switch大小写:

const response = await axios.put(url, {}, {
  validateStatus () {
    return true;
  }
});

switch (response.status) {
case 200:
  MicroService.action(data);
  break;
case 401:
  MicroService.otherAction(data);
  break;
default:
  console.error(`The server returned an unexpected ${response.status} error upon attempting to hit ${url}`);
  break;
}

答案 1 :(得分:0)

我可以想到两种选择:

1。 如果此代码在函数内部,则可以将MicroService.action(data)移至try / catch之后,并将return放入catch中(如果适用于该函数)。

2。 then语法来调用axios:

axios.put(url, {}).then((response) => {
  if (response.status === 200) {
    MicroService.action(data);
  }
}).catch((error) => {
  if (error.status === 401) {
    MicroService.otherAction(data);
  } else {
    console.error(`The server returned an unexpected ${error.status} error upon attempting to hit ${url}`);
  }
});

答案 2 :(得分:-1)

理想情况下,axios.put()MicroService.action()应该抛出明显的错误,以便您的catch块可以检测并忽略来自MicroService.action()的错误。

如果流程更复杂,并且您希望在MicroService.action()之后继续其他代码(忽略错误并继续执行,而不只是默默地忽略),则可以将其包装在嵌套的{{1}中},但这通常是要避免的模式(尽管比其他描述的选项更容易阅读和维护)