调用 websocket 连接的事件处理程序 (wss.on
) 调用异步函数 sendInitialState()
。我在那里调用了一个异步函数 (getMetadata()
),它返回一个 Promise,我在其中执行了一些异步操作。我解决了 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) =>
之前添加异步,但结果是一样的)
最佳答案
虽然 reject()'ing
promise 而不是 throw 为您解决了问题,但您的代码风格可以改进:
- 将回调转换为 Promise 时,无需将函数声明为异步函数:它只会包装到另一个 Promise 中;
- 声明函数可能比将函数表达式分配给 const 更好;
- 为了减少缩进,模式应该是
if (err) { return reject(err);
:这消除了对 else 子句的需要; - 我们可能希望重用基于 promise 的函数,因此提取通用逻辑会导致代码更具可读性;
OP 更多地是关于 promises 而不是 async/await,因此这是一个重写的版本,具有更小的功能、浅缩进并使用更多的 async/await。
wss.on('connection', (ws) => {
sendInitialState();
});
async function sendInitialState(ws) {
console.log('Sending initial state!');
const metadata = await getMetadata();
console.log('metadata:', metadata);
}
function connect(url) {
return new Promise((resolve, reject) => {
MongoClient.connect(url, (err, db) => {
if (err) {
return reject(err);
}
resolve(db);
});
});
}
function findOne(db, collectionName, object) {
return new Promise((resolve, reject) => {
db.collection(collectionName).findOne(object, (err, res) => {
if (err) {
return reject(err);
}
console.log('Metadata found: ', res);
resolve(res);
});
});
}
async function getMetadata() {
const db = await connect(url);
const res = await findOne(db, 'meta', {
type: 'a'
});
db.close();
console.log('Metadata found: ', res);
return res;
}
关于javascript - async await Promise 用法永远阻塞等待,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47601613/