【问题标题】:How does Knex await execute a database query? [duplicate]Knex await 如何执行数据库查询? [复制]
【发布时间】:2020-12-16 08:39:48
【问题描述】:

我试图了解await 关键字是如何在 KNEX 中使用的。举个例子:

knex.schema.createTable( ... );

这将返回this,它是SchemaBuilder 的一个实例。它不会在数据库中执行创建表查询。但是,如果我坚持和await 在它前面。

await knex.schema.createTable( ... );

这将在数据库中执行创建查询。

我的理解是 await 用于等待承诺解决,但在这种情况下,感觉就像发生了其他事情,因为不是 awaiting 函数不会返回承诺。

这是如何工作的?

【问题讨论】:

  • 这是我的理解,但如果我不await 函数调用它肯定不会在数据库中创建表。与我使用await 相比,它将执行查询,并且表将出现在数据库中。
  • @T.J.Crowder 前一个表达式只是创建了一个SchemaBuilder,后一个表达式调用了SchemaBuilder的.then()方法。
  • @Bergi - 为什么,为什么我没有想到自定义 thenable??
  • @Bergi 你是对的!我没有意识到你可以设置一个 then 原型,当你使用 await 时会调用它。 await fn() 只是 fn().then() 的语法糖。谢谢!

标签: javascript node.js design-patterns async-await knex.js


【解决方案1】:

如果你想知道knex 是如何只在你在结构前面写上await 时发出请求的,那么就在这里。

在底层,knex 使用 pattern,它返回一个带有 then 字段的对象。

const asyncFunction = (delay) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      return resolve(delay);
    }, delay);
  })
}

const builder = (delay) => {
  return {
    then: async (resolve) => {
      const result = await asyncFunction(delay);
      return resolve(result);
    }
  }
}

const main = async () => {
  const array = [];
  for(let i=0; i<10; i++) {
    array.push(builder(i));
  }
  console.log('array', array);
  console.log('array[0]', array[0]);
  console.log('await array[0]', await array[0]);
  console.log('Promise.all for array', await Promise.all(array));
}

main();

此执行的结果将是控制台的以下输出

array [
  { then: [AsyncFunction: then] },
  { then: [AsyncFunction: then] },
  { then: [AsyncFunction: then] },
  { then: [AsyncFunction: then] },
  { then: [AsyncFunction: then] },
  { then: [AsyncFunction: then] },
  { then: [AsyncFunction: then] },
  { then: [AsyncFunction: then] },
  { then: [AsyncFunction: then] },
  { then: [AsyncFunction: then] }
]
array[0] { then: [AsyncFunction: then] }
await array[0] 0
Promise.all for array [
  0, 1, 2, 3, 4,
  5, 6, 7, 8, 9
]

如您所见,then 函数内部的代码在使用 await 关键字或其他等待Promise 的方式之前不会被调用。

【讨论】:

  • 不要忘记then 的第二个参数。此外,我建议不要将 then 设为 async function 以避免奇怪的拒绝处理。只需{ then(...args) { return asyncFunction().then(...args); } }
猜你喜欢
  • 2017-11-24
  • 2021-03-23
  • 2014-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多