If you want to know how knex
only makes requests when you write await
in front of the construct, then here.
Under the hood, knex
uses a pattern
that returns an object with a then
field.
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();
The result of this execution will be the following output to the console
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
]
As you can see, the code inside the then
function will not be called until the await keyword or other ways of waiting for Promise
are used.