I've stumbled upon an interesting but rather hacked way to write linear code with promises in Javascript, as follows:
const return_by_death = new Promise((resolve) => {});
and
const signup = async (req, res) => {
const user = req.body.username;
const pass = req.body.password;
if(!user || !pass) {
res.sendStatus(400);
return;
}
const hash_data = await generate_hash(pass).catch(async (err) => {
res.sendStatus(500);
await return_by_death;
});
const new_account = new models.account.model({
username: user,
salt: hash_data.salt,
hash: hash_data.hash
});
// ...
};
and from my experimentation, it seems to work in the way that if the promise from generate_hash is rejected, it will go into my error handler without moving on to the new_account line. My questions are as follows:
Does this waste memory, by generating promises or execution threads that just hang indefinitely?
Does expressjs hold on to functions passed into app.get(path, func) where it would be keeping track of the signup promise that might never resolve?
Is there a better way to do this?
EDIT: based on the answer/information from @CertainPerformance I came up with the following solution
class PromiseRunError {
constructor(obj) {
this.obj = obj;
}
}
Promise.prototype.run = function() {
return this.catch((err) => {return new PromiseRunError(err)}).then((data) => {
if(data instanceof PromiseRunError) {
return [undefined, data.obj];
}
return [data, undefined];
});
};
and
const [hash_data, hash_gen_err] = await generate_hash(pass).run();
if(hash_gen_err) {
res.sendStatus(500);
return;
}