Knex.js 非终止函数

Knex.js non-terminating functions

我对这个问题没有任何问题,我只是对knex.js如何处理某事感兴趣。

在代码中,可以这样写

let search = knex.table('users').select('something')
if(params.minprice) search.where('minprice', params.minprice)
if(something) search.something()
let result = await search

它有效,但我不明白他们是如何设法在 await 发生之前暂停查询执行的?如果我们确实等待,这意味着函数是异步的,也就是返回了一个承诺。但是在 javascript 中,promise 会在调用返回它的函数时立即执行,它不关心是否存在 .then() 或 .catch()。查询执行不应该从第 1 行开始吗?更何况我log搜索的时候,不是promise,而是某种object,怎么能等到呢?

有人可以提供一个简单的例子来实现这种行为吗?

我猜测 search 包含一个名为 then 的 属性,这是一个启动搜索的函数,其行为也类似于 Promise.prototype.then 的功能.

例如:

// define Searchable
let Searchable = function() {
  this.searchParam = 'param';
};
Searchable.prototype = {
  setSearchParam: function(p) { this.searchParam = p; },
  initiateSearch: async function() {
    // lots of fancy searching
    console.log(`Searching with param "${this.searchParam}"`);
    return `search based on "${this.searchParam}"`;
  },
  then: async function(callback) {
    // initiate the search:
    let searchResults = await this.initiateSearch();
    
    // behave kind of like `Promise.prototype.then`!
    return callback(searchResults);
  }
};

// now work with it:
(async () => {
  
  let searchable = new Searchable();
  searchable.setSearchParam('mySearchParam');
  
  console.log('No search performed yet!');
  
  // Here's the fancy usage you're concerned with (it invokes `searchable.then`):
  let searchResult = await searchable; 

  console.log('RESULT:', searchResult);
  
})();

在某些 value 上调用 await 将尝试调用 value.then,就好像它是接受回调参数的函数一样。

Knex 查询生成器是可变的 thenable 对象。

因此,每次您为该查询生成器调用 search.where(...) 时,其内部状态都会发生变化并存储新的 where 子句。

查询构建器是 thenable 意味着对象有 .then() 方法,当你调用 await search 它实际上与 await Promise.resolve(search) 相当,后者首先执行 thenable 和将其转换为 promise,然后被解决,否则可能会发生异常。

Thenable 对象实际上是承诺规范中非常重要的部分,提供承诺和非承诺对象之间的互操作性API。