【发布时间】:2018-05-16 01:03:54
【问题描述】:
调用 websocket 连接的事件处理程序 (wss.on) 调用异步函数 sendInitialState()。在那里我调用了一个异步函数 (getMetadata()),它返回一个 Promise,我在其中执行了一些异步操作。我解决了这个承诺,resolve(res) 被调用了,但是程序仍然阻塞等待,也就是说,console.log(metadata) 永远不会被调用。
wss.on('connection', (ws) => {
sendInitialState();
});
const sendInitialState = async (ws) => {
console.log('Sending initial state!');
const metadata = await getMetadata();
console.log('metadata:', metadata);
};
const getMetadata = async () => {
return new Promise((resolve, reject) => {
MongoClient.connect(url, (err, db) => {
if (err) {reject(err);}
else {
db.collection("meta").findOne({type: 'a'}, (err, res) => {
if (err) reject(err);
else {
db.close();
console.log('Metadata found: ', res);
resolve(res);
}
});
}
});
});
}
我的程序阻塞的原因是什么?
(我尝试在外部(ws) =>之前添加异步,但结果是一样的)
【问题讨论】:
-
对于初学者来说,
if (err) throw err是错误的,在你拥有它的两个地方都应该是if (err) return reject(err);。为了将来参考,if (err) throw err几乎永远不会出现在您的代码中。我从未遇到过正确错误处理的情况。然后你需要在你的await周围加上一个try/catch,这样你就可以捕捉到任何可能发生的错误。错误处理在这里不容忽视,当事情没有按预期工作时,这可能是您应该首先查看的内容。 -
另外,它应该是
console.log('metadata:', blockchainMetadata);。您在日志语句中引用了错误的变量。 -
@jfriend00 Promise 自动将任何抛出的错误转换为可以在
catch()中捕获的被拒绝的 Promise。为什么throw在这种情况下无效,这不只是性能问题,因为throw周围没有优化吗? -
@peteb - 该代码不在承诺回调中。它在数据库异步回调中。那里没有自动转换来拒绝。
-
没有。
reject()只是一个普通的函数调用。您的函数会继续执行块中的其余代码。您应该使用常规流控制将要在错误路径中执行的代码与非错误路径分开。常规 Javascript 编程技术。
标签: javascript node.js asynchronous promise async-await