在使用 express 渲染页面之前等待所有 mySql 请求完成

时间:2021-04-08 19:04:33

标签: javascript mysql node.js asynchronous

我有一个 node.js 服务器,它在用户选择他想要查看状态的储物柜类型后查询数据库。储物柜有多种状态:已殖民、未更新、空闲、已占用。获取任何这些类别都是通过特定请求完成的。

我想要的是,如果用户选择所有选项,则能够执行所有请求并将所有行放入一个数组中,然后用它呈现网页。问题是异步的,```connection.query```` 没有顺序返回,不知道怎么解决。

app.get('/admin/sites/lockers/*', function (req, res) {
    console.log("GET /admin/sites/lockers");
    let parsedQs = querystring.parse(url.parse(req.originalUrl).query);
    console.log(parsedQs);
    let resultArray = [];

    if(parsedQs['colonised']) {
        let query = fs.readFileSync('./sql/colonised_lockers.sql', 'utf8');
        connection.query(query, function (err, results, fields) {
            resultArray.push(results[0]);
            console.log("colonized :", resultArray);
        });
    }

    if(parsedQs['non_renewed']) {
        let query = fs.readFileSync('./sql/non_renewed_lockers.sql', 'utf8');
        connection.query(query, function (err, results, fields) {
            resultArray.push(results[0]);
            console.log("non_renewed :", resultArray);
        });
    }

    if(parsedQs['free']) {
        let query = fs.readFileSync('./sql/free_lockers.sql', 'utf8');
        connection.query(query, function (err, results, fields) {
            resultArray.push(results[0]);
            console.log("free :", resultArray);
        });
    }
    console.log("finally :", resultArray);
    res.render('admin/lockerView.ejs', {lockers : resultArray });
});

1 个答案:

答案 0 :(得分:1)

您可以尝试在您用来连接数据库的工具的文档中找到基于 Promise 而不是 callback 的方法。但是您也可以将 connection.query 包装到 Promise 中并使用 async await 以便在处理程序中具有“类似同步”流程。类似的东西:

function makeDBQuery(query) {
  return Promise((resolve, reject) => {
    connection.query(query, function (err, result) {
      err ? reject(err) : resolve(result);
    });
  });
}

app.get('/admin/sites/lockers/*', async function (req, res) {
  console.log('GET /admin/sites/lockers');
  const parsedQs = querystring.parse(url.parse(req.originalUrl).query);
  console.log(parsedQs);
  const resultArray = [];

  if (parsedQs['colonised']) {
    const query = fs.readFileSync('./sql/colonised_lockers.sql', 'utf8');
    const result = await makeDBQuery(query);
    resultArray.push(result);
  }

  if (parsedQs['non_renewed']) {
    const query = fs.readFileSync('./sql/non_renewed_lockers.sql', 'utf8');
    const result = await makeDBQuery(query);
    resultArray.push(result);
  }

  if (parsedQs['free']) {
    const query = fs.readFileSync('./sql/free_lockers.sql', 'utf8');
    const result = await makeDBQuery(query);
    resultArray.push(result);
  }
  console.log('finally :', resultArray);
  res.render('admin/lockerView.ejs', { lockers: resultArray });
}); 

当然你在这里需要一些错误处理程序,你可以将重复的代码移动到附加函数中,但这是另一回事)