尽管被捕获,生成器内部抛出的错误还是完成了它

2024-04-13

我有一个异步生成器函数,它内部调用几个可能引发错误的异步函数。我想要的是,当错误发生时,生成器只是记录它,然后继续进一步工作。所以我有这样的代码......

async * getAll (somestuff) {
  try {
    const thing = await fetchThing()
    const otherThing = await fetchAnother()

    yield {
      ...thing,
      ...otherThing
    }
  } catch (error) {
    console.log('Error happened, but thats ok, I want to continue')
  }
}

但是当错误发生时,它会被 catch 块记录下来,但随后生成器会产生 { did: true } 并且操作停止。 我尝试在 catch 块中的 console.log 之后手动生成 null,但结果相同。


这种“问题”与发电机本身无关,只是与发电机有关await内部机制try..catch块,因为每当一个 Promise 在 try-catch 块内被拒绝时,catch已加入(除非 Promise 是单独的 try-catch)。

事实上,生成器无法再进一步,因为一旦catch以某种方式达到,它将继续直到另一个yield被调用。如果不需要调用任何一个,它就会完成给出done: true,这就是生成器的预期行为。

您的主要问题是您期望生成器产生所有值,但它只是can't,因为yield块是从未达到:

try {
    const thing = await fetchThing()
    const otherThing = await fetchAnother()

    yield { // <-- never met if either thing or otherThing are rejected.
      ...thing,
      ...otherThing
    }
  } catch (error) { // <-- this block is reached whenever either thing or otherThing raise an exception.
    console.log('Error happened, but thats ok, I want to continue')
  }

如果你想要你的try..catch如果任何一个内部可等待元素引发异常,则阻止继续,您还需要尝试捕获它们,以便可以进一步控制它们的“失败”行为:

try {
    let thing, otherThing;
    try {
       thing = await fetchThing()
       otherThing = await fetchAnother()
    }
    catch (innerException) {
       console.log('either of the above failed!', innerException);
    }
    // in this way, the below block will be reached.
    yield {
      ...thing,
      ...otherThing
    }
  } catch (error) {
    console.log('Error happened, but thats ok, I want to continue')
  }

这样一来,无论是双双失败,还是双双成功yield将到达块并将继续执行。

这是一个显示上述内容的示例:

const fakeAsync = async () => await Promise.resolve(true);
const fakeAsyncReject = async () => await Promise.reject(false);

async function* getAll(someStuff) {
  try {
    let res, raiseExc;
    try {
      res = await fakeAsync();
    }
    catch (innerResException) {
      console.log('an inner exception raised.');
    }

    try {
      raiseExc = await fakeAsyncReject();
    }
    catch (innerRaiseException) {
      console.log('an inner exception was raised.', innerRaiseException);
    }
    // yield block, always reached unless there is something really wrong in this try block, like syntax errors or whatever.
    yield {
      res,
      raiseExc
    }
  }
  catch (error) {
    // catch block raised only when the try block above yields an exception, NOT raised when either of the try-catch blocks inside the try-catch actually join the catch.
    console.log('Error happened', error);
  }
}

// Uncomment this block if you want to see how the for-await would work.
/*
(async() => {
for await (var res of getAll([])) {
console.log('res is', res);
}
})();
*/

(async() => {
  const asyncIterator = getAll([]);
  console.log(await asyncIterator.next());
})();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

尽管被捕获,生成器内部抛出的错误还是完成了它 的相关文章

随机推荐

  • 具有非常大的数字的十六进制到 int C#

    我有一个 256 个字符长的字符串 其中包含一个十六进制值 EC851A69B8ACD843164E10CFF70CF9E86DC2FEE3CF6F374B43C854E3342A2F1AC3E30C741CC41E679DF6D07CE6
  • 浏览器使用什么启发式方法来缓存未明确设置为可缓存的资源?

    13 2 2 启发式到期 由于源服务器并不总是提供明确的过期时间 因此 HTTP 缓存通常会分配启发式过期时间 并采用使用其他标头值 例如上次修改时间 的算法来估计合理的过期时间 HTTP 1 1 规范没有提供具体的算法 但确实对其结果施加
  • 如何在UITextView iPhone应用程序中控制复制、粘贴、全选、定义?

    我正在使用 UITextView 在 iPhone 应用程序中工作 我想要允许用户只能复制消息和粘贴消息 But i 不想显示全选 选择 定义等 我按照下面的代码来控制选项 但是 所有选项都显示在 UITextView 单击中 BOOL c
  • Excel-VBA。移动公式而不复制它们

    我从我的宏中获取了以下代码 该代码运行良好 Cells curRow M Copy Range N curRow R curRow PasteSpecial Paste xlPasteFormulas 我想问一下有没有办法可以移动公式而不需
  • 两种方式将 wpf datagrid 绑定到数据库

    HI all 我想以两种方式绑定 WPF 数据网格 我尝试过以下 XAML
  • 为什么 UITextField.text 是可选的?

    它开始时是一个空字符串而不是 nil 即使它被显式设置为 nil 它仍然是一个空字符串 我不明白 也许是为了通过分配 nil 来轻松清除 用它编写代码很笨拙 var textField UITextField print textField
  • HTML5 画布元素上的子像素抗锯齿文本

    我对画布元素抗锯齿文本的方式有点困惑 希望你们都能提供帮助 在下面的屏幕截图中 顶部的 Quick Brown Fox 是一个 H1 元素 底部的元素是一个画布元素 上面渲染有文本 在底部 您可以看到两个 F 并排放置并放大 请注意 H1
  • 在 Android 中下载并解压 Zip 文件 [重复]

    这个问题在这里已经有答案了 我的应用程序正在从服务器下载 zip 文件并解压该 zip 文件并将文件保存到 SD 卡中 但问题是如果我下载 4 5 MB 的 zip 文件并解压它 这工作正常 但如果我下载 30 35 MB zip 文件这会
  • 在 C# 中重命名文件

    如何使用 C 重命名文件 看一眼系统 IO 文件 移动 http msdn microsoft com en us library system io file move aspx 将文件 移动 到新名称 System IO File Mo
  • Helm 中的 PostgreSQL:initdbScripts 参数

    PostgreSQL 的默认 Helm Chart 即stable postgresql 定义了一个initdbScripts允许运行初始化脚本的参数 但是 我似乎无法获得正确的格式来了解如何通过命令行发出它 有人可以提供如何填充此命令行参
  • Haskell 列表的嵌套笛卡尔积

    我想创建一种方法 可以给它一个长度列表 它会返回达到这些长度的笛卡尔坐标的所有组合 用一个例子更容易解释 cart 2 5 Prelude gt 0 0 0 1 0 2 0 3 0 4 1 0 1 1 1 2 1 3 1 4 cart 2
  • 如何使用 JCalendar 选择数组中的元素?

    我有一个 3D 数组 其中包含 38 年 12 个月和每个月 31 个条目 无论该月有多少天 就像这样 array 38 12 31 我还有一个 JCalendar 现在除了看起来很漂亮之外什么也不做 并且 JCalendar 下面有一个按
  • 关于人脸验证(相对于人脸识别)的置信度分数有什么建议吗?

    我在代码中使用特征脸 PCA 进行人脸识别 我使用了OpenCV网站上的教程作为参考 虽然这对于识别人脸非常有用 即它可以正确地告诉您谁是谁 但基于置信度分数的人脸验证 或冒名顶替者检测 验证人脸是否已注册在训练集中 根本不起作用 我计算欧
  • 查找两个数组之间的共同值

    如果我想比较两个数组并创建一个插值输出字符串 如果数组中的数组变量 y存在于x如何获得每个匹配元素的输出 这就是我正在尝试的 但没有完全得到结果 x 1 2 4 y 5 2 4 x each do num puts The number n
  • 将 0xFF 写入文件时出现问题

    我正在尝试使用 PrintStream 将 0xFF 写入 java 文件 当我使用十六进制编辑器打开文件时 其他值会正确写入文件 但应该显示 0xFF 的值却显示为 0xC3BF 使用的变量类型是int 经过几次尝试后 我还发现我可以输入
  • List>Remove() 方法

    我想在列表列表上使用 Remove 方法 但它对我不起作用 简单的例子应该说明一切 List
  • Laravel 多个 WHERE 子句

    我需要向 Laravel SQL 查询添加多个 where 子句 到目前为止我的 PHP 代码是 date default timezone set America Los Angeles today getdate year today
  • Magento 购物车未更新阿拉伯语商店视图中的数量

    我在 Magento 1 8 1 安装中遇到以下问题 我有两种商店视图 英语 默认 和阿拉伯语 在英文商店视图中 如果我将产品添加到购物车 我可以通过在数量框中输入新数量并单击更新购物车来修改数量 这会更改数量和总数 但是 当我切换到阿拉伯
  • @font-face 在 Firefox 中不配合

    我尝试了很多事情 包括单击与我的问题相关的所有问题 有很多 并尝试了他们所有的 解决方案 但没有一个对我有用 我尝试将 eot 文件包装在条件 IE 语句中 但这也不起作用 有人说如果你不在自己的服务器上托管文件 font face 将无法
  • 尽管被捕获,生成器内部抛出的错误还是完成了它

    我有一个异步生成器函数 它内部调用几个可能引发错误的异步函数 我想要的是 当错误发生时 生成器只是记录它 然后继续进一步工作 所以我有这样的代码 async getAll somestuff try const thing await fe