使用Knex.js查询DB的函数返回undefined

时间:2017-06-28 17:43:01

标签: javascript node.js

我有一个Node.js服务器,我将用它来处理一个网站。我正在尝试创建一个API来与数据库进行交互。我必须使用Knex.js来管理数据库。

Knex的初始化以及数据库及其单个表(目前)的创建都很顺利。我在这里尝试做的是一个函数,给定一个id作为参数,将查找相应的行并返回它。

我在这里创建表格:

success: function (response) {
    var appendage = [];
    $(response).find("Category").each(function () {
        var categoryName = $(this).find("Name").text();
        var categoryLink = $(this).find("Link").text();                    
        appendage.push('<a href="' + categoryLink + '">' + categoryName + '</a>');    
    });
    $(ProductRow).find('.CategoryLinkContent').append(appendage.join(","))
}

这是我正在尝试的功能。

// create tables in the database
function createDoctorsTable() {
    jcdb.schema.hasTable("doctors").then(function (exists) {
        if (!exists) {
            jcdb.schema.createTable("doctors", function (table) {
                table.integer("id");
                table.string("name").notNullable();
                table.string("surname").notNullable();
                table.string("presentation");
                table.string("professional_story");
                table.string("photo");
                table.string("mail");
                table.string("phone");
            }).then(function () {
                return Promise.all(
                    _.map(doctorsDBfile, function (v) {
                        return jcdb("doctors").insert(v);
                    })
                );
            });
        }
        else {
            return true;
        }
    });
}

然后我打电话给我需要的一切:

function getDoctorById(id) {
    var result;
    jcdb("doctors").where("id", id)
        .then(function(query) {
        result = JSON.stringify(query);
        });
    return result;
}

对getDoctorById()的调用返回undefined!如果我把console.log()放在函数中,它会正确打印行。 我做错了什么?

PS:我是js的总菜鸟,就在昨天我第一次见到它。

1 个答案:

答案 0 :(得分:2)

function getDoctorById(id) {
    var result;
    jcdb("doctors").where("id", id)
        .then(function(query) {
        result = JSON.stringify(query);
        });
    return result;
}

尝试改为:

function getDoctorById(id) {
    return jcdb("doctors").where("id", id)
        .then(function(query) {
            var result = JSON.stringify(query);
            return result;
        });
}

Promises让您更轻松地使用异步代码。 当使用then时,你实际上正在调用一个回调函数,链中前一个promise的结果作为回调函数的参数。

但是为了这样做,你必须从promise的回调(你传递给then的函数)中返回一个值,这是将在回调参数中的值,

并且还返回promise-returning-function本身(在本例中为jcdb) - 因为,请记住,只有promises才有then

遵循相同的逻辑, 你不能console.log()像你这样做的功能:

console.log(getDoctorById(2));

因为,请记住,函数返回promise,而不是值。它间接返回值/ s作为其回调函数的参数。这给了我们:

getDoctorById(2).then(function(result) {
    console.log("result:", result);
})

最后一件事, 你的第一个函数createDoctorsTable()也是异步的;在某些情况下,它可能会在getDoctorById()之前执行。

首先,让我们从您的createDoctorsTable()返回一个承诺,以便我们可以getDoctorById严格执行该承诺:

function createDoctorsTable() {
    return jcdb.schema.hasTable("doctors").then(function (exists) {
    .......

(注意:我只添加了return语句,其余的看起来不错)。

然后更改您的app.listen,使您的最终代码看起来像这样(假设init_jcdb()返回一个承诺):

// create tables in the database
function createDoctorsTable() {
    return jcdb.schema.hasTable("doctors").then(function (exists) {
        if (!exists) {
            jcdb.schema.createTable("doctors", function (table) {
                table.integer("id");
                table.string("name").notNullable();
                table.string("surname").notNullable();
                table.string("presentation");
                table.string("professional_story");
                table.string("photo");
                table.string("mail");
                table.string("phone");
            }).then(function () {
                return Promise.all(
                    _.map(doctorsDBfile, function (v) {
                        return jcdb("doctors").insert(v);
                    })
                );
            });
        }
        else {
            return true;
        }
    });
}

function getDoctorById(id) {
    return jcdb("doctors").where("id", id)
        .then(function(query) {
            var result = JSON.stringify(query);
            return result;
        });
}


app.set("port", serverPort);

    init_jcdb()
        .then(function() {
            return createDoctorsTable();
        })
        .then(function() {
            getDoctorById(2).then(function(result) {
                console.log("result:", result);
            })
        })
        .then(function() {
            /* Start the server on port 3000 */
            app.listen(serverPort, function() {
                console.log(`Your app is ready at port ${serverPort}`);
            }
        });
});

编写此代码有很多变化。

我建议你阅读更多关于JavaScript的异步模型,以及javascript中的承诺。