fetch - 在`fetch`上使用Fluture`encaseP`时出现UnhandledPromiseRejectionWarning
问题描述
我刚刚开始使用Flutures,我正在尝试获取一些远程数据以使用 d3 进行可视化。
我创建了一个函数,它接受一个 DOM 选择器(例如#my-chart
)和一个 url(例如https://example.com/data.json
)。
如果在获取数据时发生错误,我有一个显示错误消息的一元函数。如果一切顺利,我有一个绘制可视化的一元函数。为了简单起见,我们假设这些函数只是console.error
和console.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);
};
解决方案
这里似乎发生了两件事:
- 该
data.json()
函数不应该被包裹在里面tryP
,因为根据你的第二个未损坏的例子,它同步返回(没有await
)。这将导致 Fluture 引发 TypeError(因为它希望看到一个 Promise,但得到一个 JSON 值)。虽然,知道 fetch API,data.json()
通常会返回一个 Promise,所以它也可能是你的第二个示例被破坏了,并且正在发生其他事情。不管是什么,我怀疑某个地方抛出了一个意外的错误。除了您发布的错误消息之外,您是否在控制台中看到任何其他错误消息? - 我做了一些测试,这似乎是真的——当 Fluture 在成功后引发或捕获 TypeError 时
encaseP
,似乎原始 Promise 设法捕获了该错误,并触发了未处理的拒绝。这似乎是 Fluture 中的回归错误,我会尽快修复它。同时,如果我们查明导致您的错误的原因,您将能够继续,而无需依赖上述修复。
编辑:我已经打开了一个 PR 来解决第二个问题:https ://github.com/fluture-js/Fluture/pull/310
EDIT2:该修复程序已在版本 10.3.1 下发布。使用该版本应该可以让您更深入地了解 issue 发生的情况1
。
推荐阅读
- python - 给定字符串排列的大 O 时间计算
- vue.js - Vue JS插件使用汇总和p11n不构建不是javascript错误的导入文件
- reactjs - 带有变换反应js的组件动画
- amazon-web-services - 为什么 AWS SQS 不通过长连接提供推送机制?
- ios - 如何在 iOS 的触地得分上添加不透明度?
- vba - 重置表单时出现奇怪的文本框错误?
- laravel - laravel 和验证请求
- jwt - JWT - 将刷新令牌保存为 cookie 危险吗?
- html - div Container 中的自动滚动动画
- flutter - dart:js 调用 promiseToFuture 时出错 - NoSuchMethodError: 试图调用非函数,例如 null: 'jsPromise.then'