javascript - 你如何使用 knex.js 按顺序链接查询?

标签 javascript node.js knex.js

我在理解 Knex.js 中的 promise 如何工作时遇到了一些麻烦(使用 Bluebird.js 作为 promise )。我正在尝试做一些非常简单的事情,按顺序一个接一个地执行不同的插入语句,但我一直无法让它工作。

这是我目前拥有的代码,旨在对 authentication_type 表执行插入,然后对 user_table 执行插入,然后对类别表执行插入。

// Import database connection
var knex = require('./db-connection.js');

// Add a row to authentication_type table so that user's can be created
function add_authentication_type() {
    return knex('authentication_type')
    .insert({id: 1, name: 'Internal'})
}

// Add a 'default' user with nil uuid
// Anything added without a user must link back to this user
function add_default_user() {
    return knex('user_table')
    .insert({user_table_id: knex.raw('uuid_nil()'),
            authentication_type: 1,
            authentication_token: "default"})
}

// Add categories so that locations can be created
function add_categories() {
    return knex('category')
    .insert([
    {name: "Hospital",
    description: "Where people go to get healed"},
    {name: "Police Dept",
    description: "Where people go when there’s trouble"},
    {name: "Fire Dept",
    description: "Where all the fire trucks are"}])
}

// Run the functions in the necessary order to fit constraints
add_authentication_type()
.then(add_default_user()
    .then(add_categories()))

我需要这些插入以正确的顺序发生,从上到下,这样我就不会违反我的数据库的约束。这就是我试图通过在每个调用的 .then() 部分中链接调用来对最后几行执行的操作。我认为这会使第一个查询发生,然后是第二个,然后是第三个,但情况似乎并非如此,因为我在运行此代码时遇到了违反约束的错误。

我一直在阅读 Knex 和 Bluebird 页面,但我就是无法理解它。使用 Knex 执行这种顺序查询的正确方法是什么?

最佳答案

knex 查询构建器只返回一个 promise ,所以这只是正确链接这些 promise 的问题。

TL;DR:这样做:

add_authentication_type()
  .then(add_default_user)
  .then(add_categories)

promise 链

让您的代码正常工作的关键是理解这四行做不同的事情:

// A
.then(add_default_user)
// B
.then(() => add_default_user())
// C
.then(add_default_user())
// D
.then(() => add_default_user)

then 将在前面的 promise 解析后调用作为参数传递给它的任何函数。在 A 中,它调用 add_default_user,它返回一个 promise 。在 B 中,它调用整个函数,该函数本身返回一个 promise 返回函数。在这两种情况下,then 调用一个最终返回 promise 的函数,这就是正确链接 promise 的方式。

C 不会按预期工作,因为您不是将函数传递给 then,而是函数调用的结果。因为 promises 和回调一样是异步的,所以它返回 undefined 并立即调用该函数,而不是等待之前的 promise 解决。

D 将不起作用,因为您传递给 then 的函数实际上并未调用 add_default_user!

压平链

如果您不小心,您可能会得到功能正常但可读性不佳的代码(类似于回调 hell 的“ promise hell ”)。

foo()
  .then((fooResult) => bar(fooResult)
    .then((barResult)=> qux(barResult)
      .then((quxResult)=> baz(quxResult)
      )
    )
  )

这可行,但不必要地困惑。如果传递给 then 的函数返回一个 promise,则可以在第一次 then 调用之后进行第二次调用。第一个 then 中的 promise 解析为的值将被传递给第二个 then 中的函数。这意味着上面的内容可以展平为:

foo()
  .then((fooResult) => bar(fooResult))
  .then((barResult)=> qux(barResult))
  .then((quxResult)=> baz(quxResult))

**PROTIP:**如果您对排队等候电话感到厌烦,您也可以像这样使用 Promise.resolve() 启动您的 promise 链:

Promise.resolve()
  .then(() => knex('table1').del())
  .then(() => knex('table2').del())
  .then(() => knex('table3').del())

关于javascript - 你如何使用 knex.js 按顺序链接查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46614759/

相关文章:

javascript - 使用 jquery 获取文本框值

javascript - 在 testcafe 中对偏离“.1”的数字执行断言的最佳方法是什么

regex - 使用 fs 在 multer 中重命名上传的图像

mysql - 如何使用mysql或knex和express js插入不存在的记录,如果存在则忽略它

javascript - 相同的参数传递到 HTML 但不是按钮

javascript - Chrome 开发工具,谁在设置高度/宽度?

ios - POST header 和正文之间的随机延迟

node.js - 如何停止 Node cron 作业

javascript - 按日期升序索引,但最后显示过去的日期

mysql - 为 bookshelf.js 中的子查询重写左外连接