I am new to node.js and pg-promise coming from a synchronis programming background it requires a new thinking.
I would to start with a scenario of running database initialisation before the main program logic.
Following this example: https://github.com/vitaly-t/pg-promise/wiki/Learn-by-Example#simple-select
db.any("select * from users where active=$1", [true])
.then(function (data) {
// success;
})
.catch(function (error) {
// error;
});
Would my code read as either:
db.query("DELETE FROM records")
.then(function (data) {
// success;
console.log("This is where all my main logic goes");
})
.catch(function (error) {
// error;
});
Or would it read as:
db.query("DELETE FROM records")
.then(function (data) {
// success;
})
.catch(function (error) {
// error;
});
console.log("This is where all my main logic goes");
My understanding is that with the latter the message would be displayed before the records were deleted.
Update: After reading numerous articles on promises and callbacks I understand that pg-promise uses chaining being .then and .catch for both success and error scenarios. I also now believe I understand the pg-promise command should be placed within a function wrapper such as:
function initialiseDB() {
db.query("DELETE FROM records")
.then(function (data) {
// success;
})
.catch(function (error) {
// error;
});
}
Then from within my code I would call the function with a simple command which would run the function asynchronously:
initialiseDB();
I am however still unsure of how this concept of asychronous coding and promises fits into the overall structure of a program as surely almost everything in a program would need the initialisation to be completed first. Accordingly would the entire program not need to be placed in the ".then" section of the function? i.e the only code at the top level would effectively be the intialiseDB() function?
// Start of code here
var pgp = require('pg-promise')();
//Configure the database connection
var config = {
user: 'username', //env var: PGUSER
database: 'database', //env var: PGDATABASE
password: 'password', //env var: PGPASSWORD
};
var db = pgp(config);
function initialiseDB() {
db.query("DELETE FROM records")
.then(function (data) {
// This is where the main program logic goes after this line;
})
.catch(function (error) {
// error;
});
}
// Commence the program here
initialiseDB();
pg-promise is a Postgres library for Node written on top of the brianc/node-postgres library. It's technically a wrapper for node-postgres and converts the callback interface into a promises based interface.
A promise is used to handle the asynchronous result of an operation. JavaScript is designed to not wait for an asynchronous block of code to completely execute before other synchronous parts of the code can run. With Promises, we can defer the execution of a code block until an async request is completed.
Async functions always return a promise. If the return value of an async function is not explicitly a promise, it will be implicitly wrapped in a promise. Note: Even though the return value of an async function behaves as if it's wrapped in a Promise.resolve , they are not equivalent.
PG promise actually allows for the use of generators
and async/await
on newer nodejs versions. Generators
require an adapter with promises that vitaly built into the system, so supplying a generator function
will allow for a cleaner code flow in a synchronous manner
Taken from the repository under the tag task
Without generators
:
db.task(t => {
// this.ctx = task config + state context;
return t.one('SELECT * FROM users WHERE id = $1', 123)
.then(user => {
return t.any('SELECT * FROM events WHERE login = $1',user.name);
});
})
.then(events => {
// success;
})
.catch(error => {
// error;
});
With generators
:
db.task(function * (t) {
// this.ctx = task config + state context;
let user = yield t.one('SELECT * FROM users WHERE id = $1', 123);
return yield t.any('SELECT * FROM events WHERE login = $1', user.name);
})
.then(events => {
// success;
})
.catch(error => {
// error
});
If using async/await
, you can simple replace the function * (t)
with async function (t)
and yield
with await
and it'll work much the same.
Some caveats:
In more complex logic, you should use try catch blocks around things that might fail, as they'll bubble the error in generators
and async/await
db.task(function * (t) {
yield Promise.reject(new Error('This will cause your app to error')
}
You should also pay close attention to his pg-promise demo! It'll teach you great things like the extend event, repos, external SQL files, and a lot of other great things in the library like helpers!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With