缓存承诺会导致Node.js中未处理的承诺拒绝
使用nodejsv。7.5.0我要 未处理的PromisejectionWarning&&DepractionWarning 我知道它是Node6.6以来的一部分新特性,但我不明白的是,我只是在将它缓存到变量中之后才捕捉到它的承诺。如果我不缓存它,则不会抛出任何警告。 这是引发错误的代码:缓存承诺会导致Node.js中未处理的承诺拒绝,node.js,promise,warnings,Node.js,Promise,Warnings,使用nodejsv。7.5.0我要 未处理的PromisejectionWarning&&DepractionWarning 我知道它是Node6.6以来的一部分新特性,但我不明白的是,我只是在将它缓存到变量中之后才捕捉到它的承诺。如果我不缓存它,则不会抛出任何警告。 这是引发错误的代码: let verifyPromise = verifyToken(id_token); verifyPromise.catch((err) => { log(err);
let verifyPromise = verifyToken(id_token);
verifyPromise.catch((err) => {
log(err);
});
let verifyOkPromise = verifyPromise.then((login) => {
return DB_API.getTokenById(id_token);;
});
verifyOkPromise.catch((err) => {
log('error in finding token: ', err);
});
verifyOkPromise.then((dbRes) => {
log('loggin res in finding token: ', dbRes);
});
其中verifyToken()是一个检查google auth token并返回承诺的函数。
节点输出如下所示:
error in finding token: { CouchbaseError message: 'The key does not exist on the server', code: 13 }
(node:10961) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): CouchbaseError: The key does not exist on the server
(node:10961) DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
正如您所看到的,promise error分支在按预期记录时被定期捕获,但我仍然收到警告
如果我只是像这样附加捕获:
verifyPromise.then((login) => {
return DB_API.getTokenById(id_token);;
}).catch((err) => {
log('error in finding token: ', err);
});
没有警告!!!
我想我错过了一些微妙的东西,但我不明白会是什么。
有人有线索吗?
提前感谢这个问题之所以发生,是因为最终失败的不是最初的承诺,而是
then()
!您没有存储的结果
verifyOkPromise.then((dbRes) => {
log('loggin res in finding token: ', dbRes);
});
这里对then()
的调用最终触发承诺链的解析。您试图处理来自原始调用的捕获,但失败的是链。这里有三个简化的版本来说明你要做的事情。第一个匹配您的工作流。第二个匹配通常的编写方式(但是您不想使用的模式)。第三种方法重写模式以正常工作,但使用分配给变量的结果
let Promise = require('bluebird');
function forceReject() {
return Promise.reject('deliberately failed');
}
let p = forceReject('12345');
// This will produce an Unhandled Rejection error
/*
p.then(res => { console.log('succeeded: ', res); });
p.catch(err => { console.log('failed: ', err); });
*/
// This will work but it's not the pattern you prefer
/*
p.then(res => {
console.log('succeeded: ', res);
}).catch(err => {
console.log('failed: ', err);
});
*/
// This will also work! Note the assignment of the result of p.then()...
let q = p.then(res => { console.log('succeeded: ', res); });
q.catch(err => { console.log('failed: ', err); });
你使用的是节点7.5,你应该考虑<代码>异步/等待> /代码>。Chad的答案写得很好,也很正确,但下面是我编写问题代码的方式:
async function whateverYoureDoing(id_token) {
const token = await verifyToken(id_token);
// catch will automatically propagate.
//You can use regular try/catch and if rethrow your own custom TokenInvalidError object
const dbRes = await DB_API.getTokenById(id_token);
console.log('loggin res in finding token: ', dbRes);
}
注意:您不再需要添加
。捕获
并用承诺记录错误-这就是未处理的退出
跟踪功能的要点:)日志记录通常应该在顶层完成,因为承诺在异常情况下也能很好地工作。它也是这样工作的。我得试着去抓,否则我会得到同样的警告。许多Thanksry{token=wait verifyToken(id_token);try{dbRes=wait DB_API.getTokenById(id_token);log('loggin res in finding token:',dbRes);}catch(error){log('error in finding token:',error);/*insert verified token*/}catch(error){log(错误);}