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())