【问题标题】:Javascript neither then or await are waiting for the method to finishJavascript then 或 await 都在等待方法完成
【发布时间】:2020-10-20 04:54:10
【问题描述】:

我觉得有些重要的东西我不明白,但是谷歌的结果都很复杂。请帮帮我。

app.post('/api/trigger-push-msg/', function (req, res) {
  getAllSubscriptionsFromDatabase()
  .then(function(subscriptions) {
    console.log(subscriptions)
    ...
async function getAllSubscriptionsFromDatabase() {
  let subscriptions = [];

  await db.find({}, function (err,docs){
    subscriptions = docs;
    console.log("Docs"+docs)
    return(docs);
  })
  return subscriptions;
};

据我了解,它应该等待 getAllSubscriptions。在这种情况下,它会打印:

Docs[object 对象]

[对象对象]

但它正在打印这个:

(0) []

Docs[object 对象]

【问题讨论】:

  • 您在 DB 调用上的等待可能在这里没有做任何事情
  • 为了等待getAllSubscriptionsFromDatabase,你可能需要暴露返回的promise来表达。如果您退回它,它可能会起作用。 return getAllSubscriptionsFromDatabase()...

标签: javascript node.js asynchronous async-await


【解决方案1】:

谢天谢地,它看起来像 Express supports promises in API callbacks

这样的事情可能会奏效。通过使回调异步我们隐式返回一个承诺,确保 Express 知道等待 DB 调用。

对数据库的调用需要转换为返回一个promise,以便我们可以将它连接到promise链。

app.post('/api/trigger-push-msg/', async (req, res) => {
  const subscriptions = await getAllSubscriptionsFromDatabase()  
  console.log(subscriptions)
  // ...
})

function getAllSubscriptionsFromDatabase() {
  return new Promise((resolve, reject) => 
    db.find({}, (err, docs) => err ? reject(err) : resolve(docs))) // is that first empty object correct?
}

【讨论】:

    【解决方案2】:

    我不知道您使用什么数据库软件,但问题可能在于您期望基于回调的 API 的行为类似于基于 Promise 的 API。

    如果是这样,您必须检查您的数据库软件是否提供基于 Promise 的 API,如果没有,则将 DB 调用包装到 Promise 中,如下所示:

    const dbFind = (...args) => new Promise((rs, rj) => db.find(...args, (err, data) => {if(err) rj(err); rs(data)}))
    

    所以,这可能会起作用:

    const dbFind = (...args) => new Promise((rs, rj) => db.find(...args, (err, data) => {if(err) rj(err); rs(data)}))
    
    async function getAllSubscriptionsFromDatabase() {
      const subscriptions = await dbFind({}) // <-- No callback! Result is "returned" by `await`
      
      console.log('Subscriptions (aka. docs)', subscriptions)
      return subscriptions;
    };
    

    【讨论】:

      【解决方案3】:

      问题在于await db.find({}, callback)。 问题是大多数异步函数不会返回promise,如果你传入一个回调函数作为第二个参数。

      尝试像这样重构你的代码,简单而优雅 -

      async function getAllSubscriptionsFromDatabase() {
        let subscriptions = [];
      
        const docs = await db.find({});
        console.log(subscriptions);
        return subscriptions;
      };
      

      【讨论】:

        猜你喜欢
        • 2022-01-04
        • 1970-01-01
        • 2012-08-27
        • 2011-09-24
        • 2021-01-26
        • 2022-11-19
        • 2022-08-07
        • 1970-01-01
        • 2023-03-21
        相关资源
        最近更新 更多