0

问题摘要:所以我正在开发一个在后端有一个 SQL 数据库的程序,并且我正在使用 npm SQLite3 模块与之交谈。当我向服务器发出 HTTP 请求时,我在另一篇文章中被告知我应该对res.send其中的函数执行操作,因此在函数运行后,它将返回来自函数的任何内容。够容易吧?但后来我遇到了一个异步函数的问题.all (API Doc here)。基本上发生的事情是我调用我的数据库并将里面的所有内容返回到 database.all 中的一个对象,但是 database.all 是一个异步函数,它是无效的并且不能返回任何东西。我有一个在回调中发送对象的回调,但我不知道从那里如何处理它,或者我什至需要一个回调。

所以我的问题是:我可以从我的.all函数或回调中的某个地方发送 HTTP 响应,还是我的函数必须将数组返回到它被调用的位置?下面的代码向您展示我的意思。

事件链(Github repo 供参考)

我已经设置了一个角度控制器来在我的页面加载时发送以下 HTTP 请求:

$http.get('/LoadWaitingList')
.then(function(response) {
    // alert("HTTP request set, getting data");
    console.log(response.data);
});

当服务器(server.js)收到它时,我这样做:

app.get('/LoadWaitingList', function (req, res) {
  res.send(DatabaseFunction.loadWaitingList());
})

它在另一个名为 test.js 的文件中运行 loadWaitingList() 函数:

function  loadWaitingList() {
    var callbackFunction = function(err, response){
        var returnRow = response;
        return returnRow;
    }
    updateDB.Manager(callbackFunction);
}

这叫updateDB.Manager,又名这个人:

Manager : function(callback){
    var fs = require("fs");
    var file = "./Source/Server/Data/DaycareDB.db";
    var exists = fs.existsSync(file);
    if (!exists) {
        throw new Error("File not Found");
    }
    var sqlite3 = require("sqlite3").verbose();
    var db = new sqlite3.Database(file);
    db.all("SELECT * FROM WaitingList", function(err, row) {
        if (err){
            callback(err);
            return;
        }
        // console.log(row[0].ChildName);                   
        callback(null, row);
        return;
    });
},

所以最后我们可以看到,在db.all运行之后,我在row. row作为参数传入db.all并作为数组返回,我尝试在外部声明它db.all并将其传入然后打印出结果,但由于db.all是异步的,它总是出现空,因为函数尚未运行。

当我在调用回调后运行回调并检查对象(使用 vscode 调试器)时,returnRow其中包含来自我的数据库的正确数据。

如何发送被放入row并最终returnRow作为响应返回的数据?当我们以不同的方式获取 HTTP 请求然后res.send从回调或其他方式中执行时,是否可以执行初始函数调用?

4

2 回答 2

1

您需要查看您的回调。

app.get('/LoadWaitingList', function (req, res) {
  DatabaseFunction.loadWaitingList(function(err,data){
    if(err) {
      // handle the error here
    }
    // send the data
    res.send(data);
  }
});

现在loadWaitingList()需要将标准错误优先回调作为参数。这个回调被传递到updateDB.Manager()它将被执行的地方。

function loadWaitingList(callback) {
  updateDB.Manager(callback);
}
于 2016-11-13T06:09:18.907 回答
1

您需要将回调传递给您的loadWaitingList函数,然后res.send从该回调内部触发。就像是:

app.get('/LoadWaitingList', function (req, res) {
  DatabaseFunction.loadWaitingList(function(err, response) {
    res.send(response);
  });
});

function loadWaitingList(callback) {
  updateDB.Manager(callback);
}

这样,在您的函数完成res.send之前不会触发。loadWaitingList显然,这段代码非常基础。我没有检查错误,loadWaitingList只是将提供的内容传递callbackManager方法。您可能可以重构它并loadWaitingList完全删除。

app.get('/LoadWaitingList', function (req, res) {
  updateDB.Manager(function(err, response) {
    res.send(response);
  });
});

请记住,您想要异步运行的任何代码都必须在回调中。原始res.send代码中的 不在回调中,因此它立即运行。因此,它在loadWaitingList可以返回值之前完成。

希望这可以帮助。

于 2016-11-13T06:12:16.657 回答