异步事件和异常

时间:2018-01-01 00:40:00

标签: javascript async-await ecmascript-2017

在ES7中,我们将为JS提供asyncawait关键字。它对于常规功能看起来很有希望。但是我们如何在异步事件中处理异常?

例如

async badFunc()
{
    throw "bad";
}

var reader = new FileReader();
reader.onload = async function ()
{
    await badFunc();
}

根据我的理解,async函数将是一种语法糖,它将使用Promise的{​​{1}}和resolve函数。因此,只有在呼叫者使用reject关键字时才会捕获异常。

在上面的示例中,await行将捕获异常并重新抛出它。但由于await badFunc();处理程序可能没有在回调上调用onload,因此异常将在void中丢失。即使await也无法抓住它。

所以我的问题是。在事件中使用等待的正确方法应该是什么,以便异常不会丢失?

2 个答案:

答案 0 :(得分:0)

你是对的,async-await只是promises的语法糖。当函数返回时,任何 async 函数都会返回已解析Promise,或者当函数抛出异常时被拒绝。< / p>

async foo() {
  return 1;
}

const promise1 = foo(); // here we have a promise that will   resolve in 1

async bar() {
  throw new Error('something went wrong');
}

const promise2 = bar(); // here we have a promise that will be rejected with an error.

这些承诺可以像任何常规承诺一样处理,例如:

foo().then(…).catch(…);

async 功能内部,您可以使用 await 关键字。如果后面是promise(或类似promise的对象),它将暂停执行异步函数并等待promise的解析。如果promise解析,其结果将用作表达式的结果。如果被拒绝,将在使用 await 的行上抛出异常。

示例:

const promise3 = async baz() {
  const boo = await foo(); //  (1)
  const zoo = await bar(); // (2)
}

(1)暂停此线并等待承诺解决;在承诺解决后,boo变得相等1.

(2)暂停此线并等待承诺解决;承诺拒绝后,抛出异常。

可以使用try ... catch捕获 await 引发的错误。如果不是,它们会冒泡,这意味着promise3将被拒绝。

答案 1 :(得分:0)

async badFunc()
{
    throw "bad";
}

var reader = new FileReader();
reader.onload = function ()
{
    (async()=>{
        await badFunc();
    })().then(()=>()).catch(e=>console.log(e))
}

我已经用调用内部异步IIFE的普通事件处理程序替换了异步事件处理程序。 console.log(e)可以替换为您认为有用的任何错误例程。

请注意,您可以通过放置&{39; return x&#39;来从处理程序返回标准值。最后 - 在评估badFunc的Promise之前,它总是会触发,即使它被拒绝了。您不能根据内部承诺的已解决的状态返回值,除非您的回调期望并将评估Promise返回值。你可以链接到另一个事件监听器。

此外,虽然window.onerror没有抓住错误,unhandledrejection会在Chrome和其他一些浏览器中捕捉到它。 Firefox显然不会。这对于调试代码来说已经足够了,但是不能在生产中捕获任何东西。

相关问题