在 Node-JS 中使用 promise-object 的解析数据来呈现数据填充的网页

问题描述 投票:0回答:2

我是 Node-JS 的新手,正在尝试掌握异步概念和承诺。 我正在尝试确保在呈现网络服务器时数据库数据的可用性。

使用代码,我似乎已经实现了正确的时间——当数据可用时,函数 buildhtml 被调用。经过一夜的研究,第一次成功。

现在我正试图找到将数据传递到网络服务器/快递的正确方法。

我要找的数据现在封装在一个promise-object中,无法处理。我看过许多其他帖子,但无法为您的示例得出解决方案。

问题:以消费方式(基本上是promise对象,但没有外层promise封装)移交数据的最佳实践方案是什么?我的想法是完全错误的还是我错过了一小步?

非常感谢任何答案,并提前致谢!

//DB Load Users
const promise = new Promise((resolve, reject) => {
    db.connect(function(err) {
        if (err) throw err;
        console.log("Connected!");
        var sql = "SELECT username, useremail, userage, useruniqueid FROM users";
        db.query(sql, function(err, result) {
            if (err) throw err;
            const jsonresult = JSON.parse(JSON.stringify(result)); //to clear RowDatePacket
            resolve(jsonresult);
        });
    })
})

promise
    .then(buildhtml)

//Render (express) HTML with promise resolve after DB-query
function buildhtml() {
    app.get("/", function(req, res) {
        res.render("home", {
            data: promise
        })
    })
}

这是 console.log(promise) 在 buildhtml() 中的输出:

Connected!
Promise {
  [
    {
      username: 'admin',     
      useremail: '888883895',
      userage: '33',
      useruniqueid: 1        
    },
    {
      username: 'admin',     
      useremail: '888883895',
      userage: '22',
      useruniqueid: 2
    },
    {
      username: 'admin',
      useremail: '888883895',
      userage: '22',
      useruniqueid: 3
    },
    {
      username: 'admin',
      useremail: '888883895',
      userage: '22',
      useruniqueid: 4
    },
    {
      username: 'pushy boi',
      useremail: '[email protected]',
      userage: '65',
      useruniqueid: 5
    },
    {
      username: 'push attempt',
      useremail: '[email protected]',
      userage: '65',
      useruniqueid: 6
    },
    {
      username: 'instead of push db',
      useremail: '[email protected]',
      userage: '37',
      useruniqueid: 104
    },
    {
      username: '111',
      useremail: '111',
      userage: '11',
      useruniqueid: 111
    },
    {
      username: null,
      useremail: null,
      userage: null,
      useruniqueid: 112
    },
    {
      username: 'Max Mustermann',
      useremail: '[email protected]',
      userage: '44',
      useruniqueid: 333
    }
  ]
}
mysql node.js express asynchronous promise
2个回答
0
投票

这就是你应该如何重写它。首先,将获取 MySQL 数据的代码包装在一个函数中。

function getUsers() {
  return new Promise((resolve, reject) => {
    db.connect(function(err) {
        if (err) reject(err);
        console.log("Connected!");
        var sql = "SELECT username, useremail, userage, useruniqueid FROM users";
        db.query(sql, function(err, result) {
            if (err) reject(err);
            resolve(result[0]);
        });
    })
  })
}

请注意,我将您的

throw
s 更改为
reject
并删除了不需要的 JSON 步骤。

如果你使用像

mysql2/promises
这样的基于承诺的 mysql 库并使用连接池,那就更好了:

async function getUsers() {
   const result = await pool.query("SELECT username, useremail, userage, useruniqueid FROM users");
   return result[0];
}

相比之下好干净!

然后定义路线并在需要时调用

getUsers

app.get("/", function(req, res) {
  getUsers()
    .then(result => {
       res.render("home", {
         data: result
       })
    })
    .catch(err => {
       res.status(500);
       console.error(err);    
    });
});


0
投票

你有什么should工作但是引入了潜在的竞争条件......如果在承诺解决之前向

GET /
提出请求怎么办? Express 只会返回 404,因为它不知道路线。

不是在承诺解决后注册你的路由处理程序,而是在路由处理程序中解决承诺

app.get("/", async (_req, res, next) => {
  try {
    res.render("home", { data: await promise });
  } catch (err) {
    next(err);
  }
});

请注意,您的查询只会在您的 Express 服务器启动时执行一次。这可能是也可能不是您想要的。比较典型的做法是每次请求时执行查询。

© www.soinside.com 2019 - 2024. All rights reserved.