Lon*_*ick 5 javascript promise es6-promise oboe.js
我正在使用Oboe.js来解析一个非常大的JSON文件
const promises = [];
oboe('http://domain/my-file.js')
.node('items.*', item => {
// parseItem() returns a rejected Promise because of invalid JSON items
promises.push(parseItem(item));
})
.done(() => {
Promise.all(promises).then(() => {
doSomething();
});
})
Run Code Online (Sandbox Code Playgroud)
但我的浏览器控制台充斥着Uncaught (in promise)
.如果你写一个setTimeout()
类似的承诺,也会发生同样的情况
const promises = [];
setTimeout(() => {
promises.push(Promise.reject());
}, 500);
// some time in the future
Promise.all(promises);
Run Code Online (Sandbox Code Playgroud)
真正奇怪的是:现代浏览器的行为有所不同.在Firefox Developer Edition中,一切都在没有错误消息的情况下运行,而在Chrome中,我充斥着它Uncaught (in promise)
.在Chrome中,如果您Promise.reject();
没有捕获,您可以立即收到消息.在Firefox和Safari中没有任何反应.
那么这个解决方案是什么?忽略这条消息?我的意思是如果这种行为真的在官方承诺规范中,那么异步代码中的承诺对我来说并没有真正意义.
您的 Oboe 问题是基于 Oboe 流式传输 JSON 的事实,因此我们无法提前知道有多少个 Promise,因此我们无法提前附加责任Promise.all
。我们可以“承诺”Oboe,以便能够在其方法中返回承诺。
通常,我会使用 RxJS 从事件发射器自动创建流 - 并且 RxJS 的方法已经可以返回 Promise,然后聚合它。然而 - 由于我不想在这里使用第三方库,而且它的教学价值较小 - 让我们自己实现它:
function addMap(oboe) {
oboe.map = function(selector, mapper){
var promises = [];
return new Promise(function(resolve, reject){ // create a new promise
oboe.node(selector, function(match){
var result = mapper(match); // get result
// signal that we're handling the rejection to make sure it's not handled.
result.catch(function(){});
promises.push(result);
});
oboe.fail(reject);
oboe.done(function(){ resolve(promises); });
});
};
}
Run Code Online (Sandbox Code Playgroud)
这会让我们做:
var o = oboe("foo");
addMap(o);
o.map("items.*", item => downloadItem(item)).then(result => {
// handle result here
});
Run Code Online (Sandbox Code Playgroud)
你的setTimeout
问题很做作。绝大多数人在实践中不会编写看起来像这样的代码 - 实际上,当不针对强制您这样做的 API 时(例如 Oboe.js 示例),异步添加错误处理程序是一种非常罕见的用例。
真正奇怪的是:现代浏览器的行为不同
这是因为 Firefox 使用 GC 来检测未处理的拒绝,而 Chrome 使用计时器。then
它是实现细节 - 唯一的保证是,如果附加在微任务中(同步地或在同一轮执行的任务中),则不会记录错误。
归档时间: |
|
查看次数: |
5644 次 |
最近记录: |