javascript - async await Promise 用法永远阻塞等待

标签 javascript node.js asynchronous promise async-await

调用 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/

相关文章:

c# - 异常在异步代码块中被忽略

javascript - Rails 中的 Jquery 异步表单提交

javascript - 如何使用 css 制作自动调整水平线 DIV 大小?

javascript - Google Transliteration - 打字时的单词建议

javascript - Turbolinks、Rails、后退按钮、其他来源的页脚

mysql - Sequelize 映射不能使用 max 和 col

c# - 返回 Task 的方法应该抛出异常吗?

javascript - 我如何使用 jQuery 获取 <img> 标签内的宽度

javascript - 架构错误, 'has no method save'

node.js - 如何在 AWS Lambda 中将消息记录到 Python 中的错误日志