简体   繁体   中英

Knex.js non-terminating functions

I don't have any problem in this question, I am just interested in how knex.js menaged to something.

In code, you can write something like this

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

It works, but I don't get how did they menage to hold query execution until await occured? If we did await, it means function was async aka returned a promise. But in javascript, promise executes as soon as function that returned it is called, it does not care is there .then() or .catch(). Should not query execution start al line 1? What is more, when I log search, it is not a promise, but some kind of object, so how can it be awaited?

Can someone provide a simple example how to achieve such a behaviour?

I'm guessing that search contains a property named then , which is a function that initiates the search and also behaves similarly to the functionality of Promise.prototype.then .

Eg:

 // 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); })(); 

Calling await on some value will attempt to call value.then as if it were a function accepting a callback argument.

Knex query builder is mutable and thenable object.

So every time you call for example search.where(...) for that query builder, its internal state changes and stores that new where clause.

Query builder being thenable means that the object has .then() method and when you call await search it is actually pretty much equivalent with await Promise.resolve(search) which first executes thenable and converts it to promise which is then resolved or an exception might occur.

Thenable objects are actually pretty important part of promise spec providing interoperability API between promises and non-promise objects.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM