Sea*_*yer 7 javascript node.js knex.js
我在理解Knex.js中的承诺如何工作(使用Bluebird.js作为承诺)时遇到了一些麻烦.我正在尝试做一些非常简单的事情,按顺序依次执行不同的插入语句,但我无法让它工作.
这是我到目前为止的代码,它意味着在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()))
Run Code Online (Sandbox Code Playgroud)
我需要从上到下以正确的顺序发生这些插入,所以我不违反我的数据库的约束.这就是我在最后几行中通过在每次调用的.then()部分中链接调用来尝试做的事情.我认为这会使第一个查询发生,然后是第二个,然后是第三个,但这似乎并非如此,因为我在运行此代码时遇到约束违规错误.
我一直在阅读Knex和Bluebird页面,但我无法掌握它.使用Knex执行此类顺序查询的正确方法是什么?
knex查询构建器只返回一个promise,所以这只是正确链接这些promise.
TL; DR:这样做:
add_authentication_type()
.then(add_default_user)
.then(add_categories)
Run Code Online (Sandbox Code Playgroud)
让代码工作的关键是理解这四行做不同的事情:
// A
.then(add_default_user)
// B
.then(() => add_default_user())
// C
.then(add_default_user())
// D
.then(() => add_default_user)
Run Code Online (Sandbox Code Playgroud)
then在前面的promise解析之后,将调用任何函数作为参数传递给它.在A它的调用中add_default_user,它返回一个promise.在B,它调用整个函数,它本身返回一个promise-returns函数.在这两种情况下,then调用最终返回promise的函数,这就是您正确链接promise的方式.
C将无法按预期工作,因为您没有传递函数then,而是函数调用的结果.因为promises(如回调)是异步的,所以返回undefined并立即调用该函数,而不是等待先前的promise来解析.
D将无法正常工作,因为您传入的功能then实际上并没有调用add_default_user!
如果你不小心,你可能会得到功能性但不完全可读的代码(一个类似于回调地狱的"承诺地狱").
foo()
.then((fooResult) => bar(fooResult)
.then((barResult)=> qux(barResult)
.then((quxResult)=> baz(quxResult)
)
)
)
Run Code Online (Sandbox Code Playgroud)
这有效,但不必要地混乱.如果传递的函数then返回一个promise,则第一个then调用可以跟随第二个调用.然后,第一个中的promise所解析的值将被传递给第二个中的函数.这意味着以上内容可以扁平化为:
foo()
.then((fooResult) => bar(fooResult))
.then((barResult)=> qux(barResult))
.then((quxResult)=> baz(quxResult))
Run Code Online (Sandbox Code Playgroud)
**PROTIP:**如果你是关于排队电话的肛门,你也可以用以下方式启动你的承诺链Promise.resolve():
Promise.resolve()
.then(() => knex('table1').del())
.then(() => knex('table2').del())
.then(() => knex('table3').del())
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3016 次 |
| 最近记录: |