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

2024-03-10

我在理解 Knex.js 中的承诺如何工作时遇到一些困难(使用 Bluebird.js 进行承诺)。我正在尝试做一些非常简单的事情,按顺序依次执行不同的插入语句,但我无法让它工作。

这是我到目前为止的代码,它的目的是在authentication_type表上执行插入,然后在user_table上执行插入,然后在category表上执行插入。

// 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 查询生成器仅返回一个承诺,因此这只是正确链接这些承诺的问题。

TL;DR:做这个:

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

承诺链

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

// 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,它返回一个承诺。在B,它调用整个函数,该函数本身返回一个承诺返回函数。在both在这些案例中,then调用一个最终返回一个 Promise 的函数,这就是正确链接 Promise 的方式。

C不会按预期工作,因为您没有将函数传递给then,但是result函数调用的。因为 Promise 与回调一样是异步的,所以 this 返回 undefined 并立即调用该函数,而不是等待前一个 Promise 解析。

D不起作用,因为您传递给的函数then实际上并没有打电话add_default_user!

压平链条

如果你不小心,你可能会得到功能正常但不完全可读的代码(类似于回调地狱的“承诺地狱”)。

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

这可行,但不必要地混乱。如果函数传递给then返回一个承诺,第一个then可以在通话后进行第二次通话。第一个 then 中的 Promise 解析为的值将被传递给第二个 then 中的函数。这意味着上面的内容可以被扁平化为:

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

**专业提示:**如果您对排队通话很苦恼,您还可以使用以下命令启动您的承诺链:Promise.resolve()像这样:

Promise.resolve()
  .then(() => knex('table1').del())
  .then(() => knex('table2').del())
  .then(() => knex('table3').del())
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 knex.js 按顺序链接查询? 的相关文章

随机推荐

  • 如何验证日历中的日期

    我已尝试使用以下代码 我已遵循示例 来测试从日历中选择的日期 如果我的数据库中不存在该日期 则应向最终用户显示验证错误消息 然而 错误并没有以
  • iOS 3 SDK 中 [NSBundle mainBundle] URLForResource:withExtension: 的替代方案是什么

    我正在使用 iOS 4 2 SDK 开发一个 iOS 应用程序 但我希望该应用程序能够在旧设备上运行 例如装有 iOS 3 1 3 的 iPhone 2G 我不知道这段代码的替代方案是什么 NSURL modelURL NSBundle m
  • 如何在 Azure 计算模拟器上配置 Web 角色以像本地 IIS(静态 URL)一样工作

    那么 问题是如何在 Azure 计算模拟器上配置 Web 角色 使其像在本地 IIS 上一样工作 我的意思是 Web 角色具有固定 url 就像您可以在项目属性中设置 使用本地 IIS Web 服务器 并设置固定 url 一样 如何将 Az
  • javascript:将参数传递给对象构造函数

    我正在编写一个jquery lib 我需要实现日期时间函数 我需要创建一个 Date 函数 它返回一个新的 Date 对象 如何将 Date args 函数的参数传递给 Date 对象构造函数以创建新的日期对象 我尝试了这样的方法 me是插
  • 导入不带 .py 扩展名的 python 模块,[重复]

    这个问题在这里已经有答案了 我同意有类似的问题 但没有一个符合我的目的 我有一个 python 脚本 没有 py 扩展名 我既不能更改文件名也不能添加符号链接 文件名很重要 我需要将上述文件导入到另一个python脚本中 我尝试过以下方法
  • ActionSheet 的工具栏问题

    我有以下示例代码 import SwiftUI struct ContentView View var body some View NavigationView NavigationLink destination DetailViewT
  • Oracle 存储过程中记录错误消息

    我们计划使用 Oracle DBMS 调度程序包将存储过程配置为每天作为批处理作业运行 我们想知道发生错误时记录错误消息的最佳方法是什么 是否可以选择记录到临时表 或者有更好的选择 提前致谢 登录临时表可能是一个很好的解决方案 例如 您可以
  • 为什么我的 MVC 项目发布后无法运行?

    我最近将我的第一个 MVC 2 项目发布到运行 Windows 2008 的商业 Web 服务器 据称该项目可以毫无问题地支持其他 MVC 站点 但遇到了一些问题 这是该项目的高级结构 正如您所看到的 这非常简单 但是 在发布站点并导航到
  • 我是 .NET 新手 - 我应该关注什么,应该忽略什么? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 因此 我在使用 php 和 Coldfusion 编程数据库驱动的 Web 应用程序方面拥有相当多的经验 不是在一起 在不同的时间 并且我开始研
  • 可以强制执行类型提示吗?

    在 python 中使用 类型提示 表示法有什么好处吗 import sys def parse arg line int gt str print arg line passing a string returning None if n
  • 如何重新启动 Hibernate 处理的 PostgreSQL 序列?

    我的任务是重新启动 PostgreSQL 数据库中许多不同序列列的序列 通常 我会简单地使用 ALTER SEQUENCE serial RESTART WITH 105 然而 Hibernate 似乎被用来处理数据库序列 我真的对Hibe
  • 持久化和刷新 - Doctrine 和 MongoDB

    冲洗 有多快 我使用 persist 将数千个项目添加到集合中 然后清空集合 然后刷新它 dm this gt get doctrine odm mongodb document manager while stuff item new I
  • Mockito:是否可以将mock与方法名称结合起来在when()调用中创建methodCall?

    我在 StackOverflow 上的第一个问题 我希望能够做类似的事情 SomeClass 模拟 模拟 SomeClass class String 方法名 someMethod 或 方法 方法 someMethod 这两件事 模拟和方法
  • 如何在 Android NDK 中使用 Asio(独立于 Boost)?

    Asio 没有 Boost 应该只使用标题就可以使用 对吗 默认情况下 Asio 是一个仅包含头文件的库 http think async com http think async com 我知道Asio内部仍然依赖Boost 这是我的设置
  • 模块与包 Android Studio

    我对 Android Studio 和 Java 非常陌生 我正在开发一个应用程序 该应用程序基本上遵循分层架构 具有不同的层 例如 UI 数据访问层 服务层等 我不清楚包和模块之间的区别 我的问题是 将所有这些不同的层放在模块或包中的哪里
  • 在 React 中将状态从一个组件设置为另一个组件的最佳实践方法

    我从最佳实践的角度提出这个问题 我在这里找到的答案是关于单个代码库的更具体的问题 如果已经得到答案 我很高兴能被指出正确的方向 或者如果我正在尝试的内容不被认为是良好的做法 我很高兴能以另一种方式显示 我可能误解了一些概念 我正在学习 Re
  • 可以重载花括号吗?

    我几乎可以肯定不是 但我没有找到明确的答案 是否可以重载花括号 如 class Foo int i public int operator int i return i 42 int main Foo f f 2 return 0 它从未被
  • C++ 中的矩阵数据类型

    C 中有一种数据类型叫矩阵吗 如果是 使用它时应该包含哪个头文件 The 升压矩阵库 http www boost org doc libs 1 42 0 libs numeric ublas doc matrix htm提供了这个 对于更
  • 寻路代码产生意外结果

    首先 请原谅这个不好的标题 但我不知道如何用一句话来描述它 给定一个包含 3 种字段的网格 空字段 墙壁和出口 我编写了一个程序来检查每个空字段 该字段是否 安全 一个人穿过那个网格 但只能非对角线行走 不能穿过墙壁 这个人从一块田地开始
  • 如何使用 knex.js 按顺序链接查询?

    我在理解 Knex js 中的承诺如何工作时遇到一些困难 使用 Bluebird js 进行承诺 我正在尝试做一些非常简单的事情 按顺序依次执行不同的插入语句 但我无法让它工作 这是我到目前为止的代码 它的目的是在authenticatio