在 `fetch` 上使用 Fluture `encaseP` 时出现 UnhandledPromiseRejectionWarning

UnhandledPromiseRejectionWarning when using Fluture `encaseP` on `fetch`

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

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

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

EDIT2:修复已在 10.3.1 版本下发布。使用该版本应该可以让您更深入地了解问题 1.

的情况。