在`fetch`上使用Fluture`encaseP`时的UnhandledPromiseRejectionWarning

时间:2019-01-15 22:30:07

标签: fetch fluture

我刚刚开始使用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);
};

1 个答案:

答案 0 :(得分:1)

这里似乎发生了两件事:

  1. 不应将data.json()函数包装在tryP内,因为根据您的第二个不破示例,它会同步返回(没有{{1} }。这将导致Fluture引发TypeError(因为它希望看到Promise,但获得JSON值)。尽管知道获取API的情况,await通常确实返回Promise,所以也有可能是您的第二个示例被破坏了,并且还有其他事情发生。不管是什么,我都怀疑某个地方抛出了意外错误。除了您发布的消息以外,您还在控制台中看到其他任何错误消息吗?
  2. 我做了一些测试,这确实是正确的-当成功data.json()后Fluture引发或捕获TypeError时,似乎原始的Promise设法捕获了该错误并触发了未处理的拒绝。这似乎是Fluture中的回归错误,我将尽快修复。同时,如果我们能够深入了解引发您的错误的原因,那么您就可以继续操作而无需依赖上述修复程序。

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

EDIT2:该修补程序已在版本10.3.1下发布。使用该版本应该可以使您对问题encaseP发生的事情有更多的了解。