【问题标题】:When are knex.js queries "promises" executed/resolved?knex.js 查询“承诺”何时执行/解决?
【发布时间】:2019-09-02 14:36:38
【问题描述】:

对于普通的 Promise,一旦当前代码停止,Promise 就会在它能够这样做时立即解决。考虑以下伪代码:

const p = SomePromiseDoingLoad();
calculatethings();
await sleepPromise();
//during sleep the promise p might/will have resolved already.
await p; //awaiting just makes *sure* the promise is already executed

但是,这如何转化为像 knex 这样的查询构建器?似乎没有办法阻止 promise 执行?

const p = knex.select('*').from('table');
//p could be executed now already.
const data = await gatherDataFromWebsite();
//p most probably will have resolved??
p.limit(data.limit) // ???

上面会发生什么,以及我如何进一步防止这可能发生?节点毕竟总是被允许尽快解决承诺,所以只是链接点就可以让它解决?

const p = knex.select('*').from('table').limit(5); 
let q = knex.select('*');
q = q.from('table');
q = q.limit(5);

或者说 knex 在推迟执行的计划背后做了什么魔术?

【问题讨论】:

  • 如果你认为这是一种攻击,那么我很抱歉 - 我会删除它 - 也许你应该意识到你不是唯一一个有时会使用错误单词或单词的人

标签: javascript asynchronous promise knex.js


【解决方案1】:

仅当您在查询对象上调用 .then() 时,Knex 才会执行网络 I/O。只要您没有在查询对象上调用 .then(),它就会简单地链接并返回查询对象而不是 Promise。

await 关键字在内部调用 Promise 的 .then() 方法,因此将 awaitknex 查询对象一起使用也会导致它返回一个 Promise。

这不是推迟执行。而是由查询对象的(不是 Promise).then() 方法触发执行。

【讨论】:

  • 这不是意味着 knex 的查询对象不遵循 Promise/A+ 规范吗?这不是说promise.all([firstquery, secondquery]) 表示查询不被称为并行吗?
  • 它是一个查询对象。不是承诺。只需要遵循knex自己的规范
  • 请注意,Promise.all()await 一样,调用事物的内部 .then() 方法,因此会意外/巧合地将 kenx 查询对象转换为 Promise。根据您的数据库服务器配置,查询可能是并行的或在数据库中排队,但 javascript 将同时执行(非顺序),因为 Promise.all() 不会在调用另一个之前等待一个完成
  • 请注意,Promise/A+ 规范的一部分并没有检查对象是否实际上是 Promise,而只是检查它是否具有所需的方法(即 .then() 和可能 .catch() 如果有错误) .为了保证库之间的兼容性,它被指定为这种方式
  • @slebetman Promises/A+ 不具体 catch。它指定then的第二个参数。
猜你喜欢
  • 1970-01-01
  • 2016-01-10
  • 2020-12-23
  • 1970-01-01
  • 1970-01-01
  • 2020-02-17
  • 1970-01-01
  • 1970-01-01
  • 2013-06-22
相关资源
最近更新 更多