我有一个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的总菜鸟,就在昨天我第一次见到它。答案 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中的承诺。