首页 > 解决方案 > 在`fetch`上使用Fluture`encaseP`时出现UnhandledPromiseRejectionWarning

问题描述

我刚刚开始使用Flutures,我正在尝试获取一些远程数据以使用 d3 进行可视化。

我创建了一个函数,它接受一个 DOM 选择器(例如#my-chart)和一个 url(例如https://example.com/data.json)。

如果在获取数据时发生错误,我有一个显示错误消息的一元函数。如果一切顺利,我有一个绘制可视化的一元函数。为了简单起见,我们假设这些函数只是console.errorconsole.log

const fn = async (selector, url) => {
// convert fetch (which returns a Promise) into a function that 
returns a Future
const fetchf = Future.encaseP(fetch);

fetchf(url)
  .chain(res => Future.tryP(_ => res.json()))
  .fork(console.error, console.log);
}

显然我在包装fetch未来时遗漏了一些东西,因为我收到了这个警告:

UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch().

如果我不得不使用async/await我会写这样的东西,这不会给我任何警告。

const fn = async (selector, url) => {
  let res;
  try {
    res = await fetch(url);
  } catch (err) {
    console.error(err);
    return;
  }
  let data;
  try {
    data = res.json();
  } catch (err) {
    console.error(err);
    return;
  }
  console.log(data);
};

标签: fetchfluture

解决方案


这里似乎发生了两件事:

  1. data.json()函数不应该被包裹在里面tryP,因为根据你的第二个未损坏的例子,它同步返回(没有await)。这将导致 Fluture 引发 TypeError(因为它希望看到一个 Promise,但得到一个 JSON 值)。虽然,知道 fetch API,data.json()通常返回一个 Promise,所以它也可能是你的第二个示例被破坏了,并且正在发生其他事情。不管是什么,我怀疑某个地方抛出了一个意外的错误。除了您发布的错误消息之外,您是否在控制台中看到任何其他错误消息?
  2. 我做了一些测试,这似乎是真的——当 Fluture 在成功后引发或捕获 TypeError 时encaseP,似乎原始 Promise 设法捕获了该错误,并触发了未处理的拒绝。这似乎是 Fluture 中的回归错误,我会尽快修复它。同时,如果我们查明导致您的错误的原因,您将能够继续,而无需依赖上述修复。

编辑:我已经打开了一个 PR 来解决第二个问题:https ://github.com/fluture-js/Fluture/pull/310

EDIT2:该修复程序已在版本 10.3.1 下发布。使用该版本应该可以让您更深入地了解 issue 发生的情况1


推荐阅读