首页 > 解决方案 > 使用 SQLite3 和 ExpressJs 时,如何确保 app.get() 在调用 db.each() 方法时不是异步的?

问题描述

我有一些前端代码可以向 URL“/api/classes”发出 GET 请求。当触发时,我的 ExpressJs 后端将加载我的 SQLite3 数据库,然后读取查询,最后将结果存储在一个对象中并返回它。我正在使用 db.each() 方法来循环我的数据库。由于 console.log 模板字符串,我知道我的循环有效。问题是当我使用 PostMan 时,我可以看到 res.send() 被立即调用,它返回一个空对象。如何确保在 db.each() 之后调用 res.send()?我知道 db.each() 接受回调,所以我尝试将 res.send() 作为参数,但这不起作用。

这是我的代码:

const express = require('express');
let sqlite3 = require('sqlite3').verbose();
const app = express();

app.get('/api/classes', (req, res) => {
    let classes = {}
    let db = new sqlite3.Database('./classes.db', (err) => {
        if (err) {
            console.error(err.message);
        }
        console.log('Connected to the classes database.');
    });   
    let sql = `SELECT CRS_CDE course_code,
                  CRS_TITLE course_name,
                  Column3 start_time,
                  Column4 end_time
            FROM spring_schedule
            WHERE CRS_TITLE IN `;

    let classNames = ['Spanish I', 'Accounting II', 'College Algebra']
    let where = '(?' + ',?'.repeat(classNames.length-1) + ')';
    sql += where;

    db.each(sql, [...classNames], (err, row) => {
        if (err) throw err;
        console.log(`${row.course_code} + ${row.course_name} +  ${row.start_time} - ${row.end_time}`);
        classes[row.course_code] = row.course_name
    });
    db.close();
    res.send(classes)
});

const port = 5000;
app.listen(port, () => console.log(`Server started on port ${port}`));

标签: node.jssqliteexpressasynchronous

解决方案


根据此处each的 api 文档,该函数有一个 [complete] 回调, 因此您的示例应该是这样的:

   db.each(sql, [...classNames], (err, row) => {
    if (err) {
    throw err;
    }
    console.log(`${row.course_code} + ${row.course_name} +  ${row.start_time} -              
     ${row.end_time}`);

    classes[row.course_code] = row.course_name

  }, () => {

          res.send(classes)

      });

推荐阅读