Wrapping async functions with callbacks within - javascript

I need to call two async functions sequentially inside a new function. Both functions use callbacks to perform asynchronous operations.
When I just call my functions one by one I am faced with the problem that, as I understand it, they are called synchronously, and the second function does not wait for the first to execute
How can I wrap them to be performed sequentially?
Code that I have:
let firstFunction = (data, callback) => {
DBCallingFirst
.asyncMethodFirst(resultObj, (err, result) => {
if (err) return callback(err);
// Some code
});
}
let secondFunction = (data, callback) => {
DBCallingSecond
.asyncMethodSecond(resultObj, (err, result) => {
if (err) return callback(err);
// Some code
});
}
let newFunction = (data, callback) => {
firstFunction(data, callback);
secondFunction(data, callback);
}
Thanks for your attention!

If you are able to use promises, or async/await, you can make this a lot cleaner. As it is, you can just do the second db operation in the callback from the first one - so that guarantees the first one completes before calling the second
let firstFunction = async (data, callback) => {
DBCallingFirst
.asyncMethodFirst(resultObj, (err, result) => {
if (err) return callback(err);
DBCallingSecond
.asyncMethodSecond(resultObj, (err, result) => {
if (err) return callback(err);
// Some code
});
});
}
EDIT: With promises, you could structure it like this:
let firstFunction = (data) => {
return new Promise(() => {
DBCallingFirst
.asyncMethodFirst(data, (err, result) => {
if (err) {
return Promise.reject();
}
return Promise.resolve(result);
});
});
}
let secondFunction = (data) => {
return new Promise(() => {
DBCallingSecond
.asyncMethodSecond(data, (err, result) => {
if (err) {
return Promise.reject();
}
return Promise.resolve(result);
});
});
}
let newFunction = (data, callback) => {
firstFunction(data).then((result1) => {
secondFunction(data).then(result2) {
}).catch(err2) {
console.error(err2);
});
}.catch((err1) => {
console.error(err1);
});
}

Return Promise from both the functions and await them like this
const firstFunction = (data) => {
return new Promise((resolve, reject) => {
DBCallingFirst.asyncMethodFirst(data, (err, result) => {
if(err) reject(err);
resolve(result);
})
})
}
const secondFunction = (data) => {
return new Promise((resolve, reject) => {
DBCallingSecond.asyncMethodSecond(data, (err, result) => {
if(err) reject(err);
resolve(result);
})
})
}
Now you can call both of them sequentially using await
const newFunction = async (data) => { // note the async part in function definition
try {
const result1 = await firstFunction(data);
const result2 = await secondFunction(data); // this will be executed only after firstFunction resolves/rejects;
} catch (err) {
console.log('Error from the function', error) // promise rejection will be caught here
}
}

Related

how to pass argument in async waterfall inital function

I am using async waterfall like this
const profileRichness = () => {
async.waterfall([
getTargetUsers,
filterUser,
], (err) => {
if (err) errorlogger(uuid(), err, "email", "abc", "acc", "acd");
else console.log('Done');
});
}
Fn that I am calling
const getTargetUsers = (callback,condition) => {
user.getUsers(condition, (err, result) => {
if (err)
callback(err);
else {
if (result.length)
callback(null, result);
else
callback('No user found');
}
});
}
const filterUser = (users, callback) => {
users = users.filter(user => {
if (!user.age || user.profile < 80) return user;
else return false;
}).filter(user => user);
callback(null,users);
}
Problem is whatever I am trying to pass in first function of waterfall it returns error that "callback is not a function" what is exactly going on

I'm getting an error when I search the database and I don't know how to solve it

I'm making a request to my database, I set the functions as asynchronous and to wait, but it still returns me undefined or Promise { pending }
how do I just return it when I have the result?
export const getGerente = async (req, res) => {
var query = "SELECT * FROM inventory;"
const r = await select(query)
console.log(r)
return res.json({message:"teste"})
}
export async function select(query) {
var teste = await client.connect(() =>{
client
.query(query)
.then((resultado) => {
console.log('sucess!!');
return resultado.rows
/*
const rows=resultado.rows
rows.map(x =>{
console.log(x.name)
})*/
})
.catch((erro) => {
console.log("erro: " + erro.message);
})
.then((teste) => {
console.log('Finished execution, exiting now');
process.exit();
});
})
}
result: Promise { pending }
I'm calling her for a request
Your select function is not awaiting the client.connect properly.
Try this for select function -
export async function select(query) {
const promisifiedRows = new Promise((resolve, reject) => {
client.connect((err) => {
if (err) {
reject(err); // err in connecting
} else {
console.log('Connected!');
client.query(query, (err, rows) => {
if (err) {
reject(err); // err while exceuting the query
} else {
resolve(rows);
}
});
}
});
});
const rows = await promisifiedRows();
return rows;
}

How can I return value from this child function in javascript

cannot return the dat[0] value from the inner function
let ite = fs.readdir(directoryPath, function (err, files) {
if (err) {
return console.log('Unable to scan directory: ' + err);
}
dat = files.filter(item => item[1] == files.length);
return dat[0];
});
You are returning from the function which will called when the operation will be finished. So returning from that function doesn't change the value of your variable.
You can use readdirSync
const res = fs.readdirSync(directoryPath);
If you don't want it to be sync you can use fs.promises with async await
let res;
(async function() {
res = await fs.promises.readdir("");
})();
I don't recommend to read sync reading because it can block the main thread. You could use a callback function by passing it as parameter to another function.
function getData(onSuccess, onError) {
fs.readdir(directoryPath, function (err, files) {
if (err) {
onError('Unable to scan directory: ' + err);
}
dat = files.filter(item => item[1] == files.length);
onSuccess(dat[0]);
});
}
getData(function(data){
console.log(data);
}, function(error){
//error here
})
We can make it as a promise method to run the code async. Here we don't block any thread. It will be running asynchronously.
function getData(directoryPath) {
return new Promise((resolve, reject) => {
fs.readdir(directoryPath, function (err, files) {
if (err) {
reject('Unable to scan directory: ' + err.message);
}
dat = files.filter(item => item[1] == files.length);
resolve(dat[0]);
});
});
}
getData(directoryPath).then((data) => {
console.log(data);
}).catch((err) => {
console.error(err);
});
// or
try {
let data = await getData(directoryPath);
} catch (error) {
console.error(error);
}

How to create three function with same name one is callback, second is promise other is async/await

I want to create a function which can be utilised in 3 ways for creating npm dependency
Promise way
callback way
async/await way
For Example
1) async/await
var mongoose = require('mongoose');
async function Connection() {
try {
await mongoose.connect('mongourl');
} catch (err) {
console.error("Connection error --->", err);
}
}
Connection();
2) Callback Style
var mongoose = require('mongoose');
mongoose.connect('mongourl', function (err) {
if (err) console.error("Connection error --->", err);
});
3) Promise Style
var mongoose = require('mongoose');
mongoose.connect('mongourl').then(() => {
}).catch(err => console.error("Connection error --->", err));
Did u absorve that mongoose.connect is same name for all types
You can try with:
const connect = (name, callback) => {
try {
const result = /* generate result */
if (callback) {
callback(null, result);
} else {
return Promise.resolve(result);
}
} catch (e) {
if (callback) {
callback(e);
} else {
return Promise.reject(e);
}
}
}
And quick usage example:
connect('John')
.then(result => { /* ... */ })
.catch(error => { /* ... */ });
connect('John', (error, result) => { /* ... */ });
async function foo() {
try {
const result = await connect('John');
} catch (error) { /* ... */ }
}
Here is an example, it's similar to #hsz, but I've put the handling for the inner callback.
If your pass a callback it does this in a callback way, if not it returns a Promise instead.
If you run the snippet you can see it in action.
I've basically created a simple setTimeout function that randomly fails, to show how error handling is also done. So to see the full effect try running the snippet a few times.
function doInner(name, callback) {
setTimeout(() => {
if (Math.random() < 0.5)
callback(null, "Did " + name);
else callback(new Error("Oops in " + name));
}, 1000);
}
function doSomething(name, callback) {
if (callback) {
doInner(name, (err, result) => {
if (callback) callback(err, result);
});
} else return new Promise((resolve, reject) => {
doInner(name, (err, result) => {
if (err) reject(err);
else resolve(result);
});
});
}
//now lets test both ways
doSomething("test callback", (err, result) => {
if (err) console.error(err);
else console.log(result);
});
(async function () {
try {
const result = await doSomething("Promise");
console.log(result);
} catch(e) {
console.error(e);
}
}());

nodejs how to use multiple await promises

how can i use multi promise await in my codes ? when i wanna use second await for second promise it throw an error
function ReadJSONFile() {
return new Promise((resolve, reject) => {
fs.readFile('import.json', 'utf-8', (err, data) => {
if (err) reject(err);
resolve(JSON.parse(data));
});
});
}
const Get_Image = async (Path) => {
Child_Process = exec('node get_image.js "'+Path+'",(err,stdout,stderr) =>
return new Promise((resolve,reject) => {
resolve(stdout);
});
}
const Catch = async () => {
let get_json_file = await ReadJSONFile(); // this works perefectly
for(var i=0;i< Object.keys(get_json_file);i++) {
console.log(await Get_Image(get_json_file[i].image_path); //but this throw error
}
}
you didn`t return a promise that is why you got an error
const Get_Image = async (Path) => {
return new Promise((resolve,reject) => {
Child_Process = exec('node get_image.js "'+Path+'",(err,stdout,stderr) =>
resolve(stdout);
});
});
}

Categories

Resources