[英]JavaScript Promise : Catching errors within chained functions
I have a function that is used to add a record to the IndexDb database:我有一个 function 用于向 IndexDb 数据库添加记录:
async function addAsync(storeName, object) {
return new Promise((res, rej) => {
// openDatabaseAsync() is another reusable method to open the db. That works fine.
openDatabaseAsync().then(db => {
var store = openObjectStore(db, storeName, 'readwrite');
var addResult = store.add(JSON.parse(object));
addResult.onsuccess = res;
addResult.onerror = (e) => {
console.log("addResult Error");
throw e;
};
}).catch(e => {
// Error from "throw e;" above NOT GETTING CAUGHT HERE!
console.error("addAsync ERROR > ", e, storeName, object);
rej(e);
});
})
}
If I try to add a duplicate key, then I expect:如果我尝试添加重复键,那么我期望:
addResult.onerror = (e) => {
console.log("addResult Error");
throw e;
}
to capture that.捕捉它。 It does.确实如此。
But then, I also expect my但是,我也期待我的
.catch(e => {
// Error from "throw e;" above NOT GETTING CAUGHT HERE!
console.error("addAsync ERROR > ", e, storeName, object);
rej(e);
})
to catch that error.捕捉那个错误。 But instead I get an "uncaught" log.但相反,我得到了一个“未捕获”的日志。
Console output:控制台 output:
addResult Error
Uncaught Event {isTrusted: true, type: "error", target: IDBRequest, currentTarget: IDBRequest, eventPhase: 2, …}
Does that final .catch only handle exceptions from the openDatabaseAsync call?最后的.catch是否只处理来自openDatabaseAsync调用的异常? I would have thought now as it is chained to the .then .我现在会想到,因为它被链接到.then 。
In summary, here's what I would expect from the above code:总之,这是我对上述代码的期望:
However, I would have thought that I should get the log from the line:但是,我原以为我应该从以下行获取日志:
console.error("addAsync ERROR > ", e, storeName, object);
before the reject is sent back to the caller of addAsync() , which may be unhandled at that point.在拒绝被发送回addAsync()的调用者之前,此时可能未处理。
Your approach would benefit form a larger overhaul.您的方法将受益于更大的检修。
async
when it's not also using await
.通常,当 function 不使用await
时,不要将其编写为async
。new Promise()
for an operation that returns a promise, such as openDatabaseAsync()
does.不要将new Promise()
用于返回 promise 的操作,例如 openDatabaseAsync openDatabaseAsync()
。 Return that promise, or switch to async/await
.返回 promise,或切换到async/await
。 On the example of IDBRequest
:在IDBRequest
的例子中:
function promisifyIDBRequest(idbr) {
return new Promise( (resolve, reject) => {
idbr.onsuccess = () => resolve(idbr.result);
idbr.onerror = (e) => reject(e.target.error);
});
}
Now you can do this:现在你可以这样做:
async function addAsync(storeName, object) {
const db = await openDatabaseAsync();
const store = openObjectStore(db, storeName, 'readwrite');
return promisifyIDBRequest(store.add(JSON.parse(object)));
}
Add a try/catch block if you want to handle errors inside of addAsync()
.如果要处理addAsync()
内部的错误,请添加 try/catch 块。
It's worth checking out existing solutions that wrap the entire IndexedDB interface with promise semantics, such as https://github.com/jakearchibald/idb .有必要检查一下现有的解决方案,这些解决方案使用 promise 语义来包装整个 IndexedDB 接口,例如https://github.com/jakearchibald/idb 。
FWIW, the promise-chain variant of the above function would look like this: FWIW,上述 function 的承诺链变体如下所示:
function addAsync(storeName, object) {
return openDatabaseAsync().then( (db) => {
const store = openObjectStore(db, storeName, 'readwrite');
return promisifyIDBRequest(store.add(JSON.parse(object)));
});
}
both variants return a promise for an IDBRequest result.两种变体都为 IDBRequest 结果返回 promise。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.