我现在正在使用expressjs,kotlin和PostgreSQL开发Web API。我以面向对象的方式组织我的项目。我还为数据库创建了一个类,它使所有经常调用的查询作为函数可用。示例:
fun addUser(firstName: String, lastName: String, password: String, classId: Int){
client.query("INSERT INTO users(first_name, last_name, password, class_id) values($1, $2, $3, $4)", arrayOf(firstName, lastName, password, classId));
}
但是当我尝试发出SELECT查询并将数据集返回给函数调用者时,这不起作用,因为查询是异步的。我已经尝试将结果分配给数据库对象的属性,并在分配值后立即使用它,但似乎在我永久检查其值时无法分配该值。有谁知道如何将值返回给函数调用者?
提前感谢您的回答。
答案 0 :(得分:2)
假设您正在使用nodejs和pg模块。
正如您所说,由于查询功能是异步的,您无法直接将结果返回给调用者。传统上在nodejs中,调用者传递一个回调函数来处理结果或错误(如果有的话)。
在Kotlin中,这看起来像是:
client.query(MY_QUERY_TEMPLATE, params) { err, result ->
if (err != null) {
// do something with the error
} else {
// do something with the result
}
}
为了使这个更整洁,你可以将结果处理程序放在自己的函数中
fun handleResult(err: dynamic, result: dynamic) {
// put your code here
}
并像这样使用它:
client.query(MY_QUERY_TEMPLATE, params, ::handleResult)
如果您不喜欢这样,您还有其他选择。 pg
库可以返回Promise
。这种抽象允许您使用这样的方法链:
app.get("/promiseStyle") { req, res ->
val params = arrayOf(42) // or something...
fun handleSuccess(result: dynamic) {
for (row in result.rows) {
res.write(row.someField)
}
res.end()
}
fun handleError(error: dynamic) {
res.status(500).send("Something went wrong");
}
client.query(MY_QUERY_TEMPLATE, params)
.then(::handleSuccess)
.catch(::handleError)
}
您可能会发现以下声明对于访问各种pg客户端功能非常有用:
@JsModule("pg")
external object pg {
class Client {
fun query(query: String, params: Array<Any>): dynamic
fun query(
query: String, params: Array<Any>, cb: (dynamic, dynamic) -> Unit
)
fun connect()
}
}
然后可以按如下方式初始化postgres客户端:
val client = pg.Client()
client.connect()