I tried to send my variable back from foreground.js to background.js by using an unchanged variable, and it works. Now I can't send some data that I use my AddEventListener syntax to store the data into the variable to call its back to background.js here are my code on foreground.js
foreground.js
console.log("foreground.js injected");
var pswdBtns = [];
let hrefLists = [];
var data = {};
var i;
function readUUID(){
var navigator_info = window.navigator;
var screen_info = window.screen;
var uid = navigator_info.mimeTypes.length;
uid += navigator_info.userAgent.replace(/\D+/g, '');
uid += navigator_info.plugins.length;
uid += screen_info.height || '';
uid += screen_info.width || '';
uid += screen_info.pixelDepth || '';
return uid;
}
async function passwordProtected(pointerList){
const date = new Date();
const uid = readUUID();
alert("You are in dangerous on \'"+ pointerList.title + "\' row = " + pointerList.id.slice(20));
data = {
"Webtitle": pointerList.href,
"Title": pointerList.title,
"Time": date.toString(),
"UUID": uid
}
console.log("foreground = ", data);
return data;
}
console.log("Start loop")
//This function made for collect each id in passwordShowPasswordButton
for(i = 0; i<=pswdBtns.length; i++){
if(document.querySelector("#passwordShowPasswordButton_"+ i) == null){
console.log("This is your limit!!");
}
else{
hrefLists[i] = document.querySelector("#passwordWebsitelink_"+ i);
pswdBtns[i] = document.querySelector("#passwordShowPasswordButton_"+ i);;
data = pswdBtns[i].addEventListener('click', passwordProtected.bind(pswdBtns[i], hrefLists[i]));
console.log(hrefLists[i].title); /* Title VARCHAR(30) */
console.log(hrefLists[i].href); /* Website VARCHAR(50) */
}
}
console.log("End");
and these are my code on background.js
background.js
const edgePswd = "edge://settings/passwords";
const settingPage = "edge://settings/";
chrome.tabs.onActivated.addListener(async (tab) => {
await chrome.tabs.get(tab.tabId, (current_tab_info) => {
var pswdPageChecked = 1;
while(pswdPageChecked < 2) {
if (edgePswd == current_tab_info.url) {
chrome.tabs.executeScript(null, { file: "/extension/foreground.js" }, (data) => {
console.log("Coming to foreground");
console.log(data);
});
pswdPageChecked++;
}
}
});
});
It would be a pleasure if someone can figure this.
I have researched a lot but have not found solution for my scenario. I have a simple html/javascript app and I package it using cordova. The html page has a form which posts forms to server. I want to save form to sqlite database when the app is offline or no internet connection available.
I am new to sqlite and I have not found any compatible data type to store form to database. If I use TEXT or BLOB it simply stores "[Object HTMLFormObject]" string.
Please check me js code:
db = window.sqlitePlugin.openDatabase({
name: 'ambdb',
location: 'default'
}, function (db) {
db.transaction(function (tx) {
tx.executeSql('CREATE TABLE IF NOT EXISTS FORMS (form BLOB)');
}, function (err) {
alert('Open database ERROR: ' + JSON.stringify(err));
});
});
function storeForms(formRecieved) {
//alert(formRecieved.toString());
//alert('text(): '+ formRecieved.text());
//var jsonString = JSON.stringify(formRecieved);
//var htmlText = escape(formRecieved.innerHTML);
//var htmlText = formRecieved.innerHTML;
//var simplyString = String(formRecieved);
db.transaction(function (tx) {
tx.executeSql('INSERT INTO FORMS (form) VALUES (?)', [formRecieved]);
}, function (err) {
alert('StoreForms ERROR: ' + JSON.stringify(err));
});
}
function readForms(cb) {
var submittedForms = [];
db.transaction(function (tx) {
tx.executeSql('SELECT form FROM FORMS', [], function (tx, results) {
alert('total items: ' + results.rows.length);
for (var i = 0; i < results.rows.length; i++) {
var row = results.rows.item(i)['form'];
//row = JSON.parse(row);
/*var varstring = row.toString();
alert('tostring: ' + varstring);
var parser=new DOMParser();
var x = parser.parseFromString(varstring, "text/html");
alert('x: '+ x);*/
submittedForms.push(row);
}
cb.call(this, submittedForms);
});
});
}
document.addEventListener("online", function (e) {
alert('I am online');
isConnected = true;
var promise1 = new Promise(function (resolve, reject) {
readForms(function (forms) {
resolve(forms);
});
}).then(function (submittedForms) {
var numberOfRows = submittedForms.length;
alert('submittedForms.length: ' + numberOfRows);
if (numberOfRows > 0) {
for (var i = 0; i < numberOfRows; i++) {
alert('Single row: '+ JSON.stringify(submittedForms[i]));
submittedForms[i].submit();
}
//deleteForms();
return false;
}
})
}, false);
The commented code shows the possible ways I have tried to serialize-parse HTML object back and forth just to store it in database.
Please guide me what column data type should I use and how should I handle it in code. Many thanks!
I ended up converting HTMLFormObject to JSON object. And I am saving it as a string in database. And while reading from database, I am parsing it back to JSON object. From this JSON object I am creating a html form.
function storeForms(formRecieved) {
var elements = formRecieved.elements;
var newForm = {};
for (var i = 0; i < formRecieved.length; i++) {
var elementName = elements[i].name;
newForm[elementName] = elements[i].value;
}
var jsonString = JSON.stringify(newForm);
db.transaction(function (tx) {
tx.executeSql('INSERT INTO FORMS (form) VALUES (?)', [JSON.stringify(newForm)]);
}, function (err) {
alert('StoreForms ERROR: ' + JSON.stringify(err));
});
}
function readForms(cb) {
var submittedForms = [];
db.transaction(function (tx) {
tx.executeSql('SELECT form FROM FORMS', [], function (tx, results) {
var row, formToSubmit, input, jsonRow = {};
for (var i = 0; i < results.rows.length; i++) {
row = results.rows.item(i)['form'];
jsonRow = JSON.parse(row);
formToSubmit = createFormToSubmit(jsonRow);
submittedForms.push(formToSubmit);
}
cb.call(this, submittedForms);
});
});
}
function createFormToSubmit(jsonData) {
var formToSubmit = document.createElement("form");
var keys = Object.keys(jsonData);
var fieldName, input;
for (var i = 0; i < keys.length; i++) {
fieldName = keys[i];
input = document.createElement("input");
input.type = "text";
input.name = keys[i];
input.value = jsonData[fieldName];
formToSubmit.appendChild(input);
}
formToSubmit.setAttribute('method', "post");
formToSubmit.setAttribute('action', "https:url");
formToSubmit.setAttribute('target', "transFrame");
return formToSubmit;
}
Here is the line (50) where this is happening:
var meetingId = meeting._id.toString(),
And here is the full, relevant code:
var MongoClient = require('mongodb').MongoClient;
var assert = require('assert');
var ObjectId = require('mongodb').ObjectID;
var config = require('./config'),
xlsx = require('./xlsx'),
utils = require('./utils'),
_ = require('lodash'),
url = config.DB_URL;
var meetings = [];
function findNumberOfNotesByMeeting(db, meeting, callback) {
var meetingId = meeting._id.toString(),
meetingName = meeting.name.displayValue,
attendees = meeting.attendees;
host = meeting.host;
var count = 1, pending = 0, accepted = 0;
console.log("==== Meeting: " + meetingName + '====');
_.each(attendees, function(item) {
console.log(count++ + ': ' + item.email + ' (' + item.invitationStatus + ')');
if (item.invitationStatus == 'pending') { pending++; }
else if (item.invitationStatus == 'accepted') { accepted++; }
});
console.log("*** " + attendees.length + ", " + pending + "," + accepted);
db.collection('users').findOne({'_id': new ObjectId(host)}, function(err, doc) {
var emails = [];
if (doc.emails) {
doc.emails.forEach(function(e) {
emails.push(e.email + (e.primary ? '(P)' : ''));
});
}
var email = emails.join(', ');
if (utils.toSkipEmail(email)) {
callback();
} else {
db.collection('notes').find({ 'meetingId': meetingId }).count(function(err, count) {
if (count != 0) {
console.log(meetingName + ': ' + count + ',' + attendees.length + ' (' + email + ')');
meetings.push([ meetingName, count, email, attendees.length, pending, accepted ]);
}
callback();
});
}
});
}
function findMeetings(db, meeting, callback) {
var meetingId = meeting._id.toString(),
host = meeting.host;
db.collection('users').findOne({'_id': new ObjectId(host)}, function(err, doc) {
var emails = [];
if (!err && doc && doc.emails) {
doc.emails.forEach(function(e) {
emails.push(e.email + (e.primary ? '(P)' : ''));
});
}
var email = emails.join(', ');
if (utils.toSkipEmail(email)) {
callback();
} else {
db.collection('notes').find({ 'meetingId': meetingId }).count(function(err, count) {
if (count != 0) {
var cursor = db.collection('meetings').find({
'email': {'$regex': 'agu', '$options': 'i' }
});
}
callback();
});
}
cursor.count(function(err, count) {
console.log('count: ' + count);
var cnt = 0;
cursor.each(function(err, doc) {
assert.equal(err, null);
if (doc != null) {
findNumberOfNotesByMeeting(db, doc, function() {
cnt++;
if (cnt >= count) { callback(); }
});
}
});
});
});
}
MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
findMeetings(db, function() {
var newMeetings = meetings.sort(function(m1, m2) { return m2[1] - m1[1]; });
newMeetings.splice(0, 0, [ 'Meeting Name', 'Number of Notes', 'Emails' ]);
xlsx.writeXLSX(newMeetings, config.xlsxFileNameMeetings);
db.close();
});
});
As you can see, the meeting variable (which I am almost 100% sure is the problem, not the _id property) is passed in just fine as a parameter to the earlier function findNumberOfNotesByMeeting. I have found some information here on SO about the fact that my new function may be asynchronous and needs a callback, but I've attempted to do this and am not sure how to get it to work, or even if this is the right fix for my code.
You're not passing the meeting object to findMeetings, which is expecting it as a second parameter. Instead of getting the meeting object, the function receives the callback function in its place, so trying to do meeting._id is undefined.
In fact, what is the purpose of the findMeetings function? It's name indicates it can either find all meetings in the database, or all meetings with a specific id. You're calling it without a meeting id indicating you might be trying to find all meetings, but its implementation takes a meeting object. You need to clear that up first.
I have a for loop going through a JSON array - with help from this stack question
Whilst looping the script does the following:
- Does the JSON item exist in the tables?
- if yes
- Is the data different?
- if yes
- Update
- if no
- Do nothing
- if no
-insert into database
I found this question which allowed me to query on each for loop so I am able to get the names from the JSON and query them correctly :
for(var i=0; i<content.prices.length; i++) {
var price = content.prices[i].price
var itemName = content.prices[i].market_hash_name;
var q = "SELECT * FROM prices WHERE item = ?";
(function() {
var iNameCopy = itemName;
var priceCopy = price;
connection.query(q, iNameCopy, function (err, results) {
if (err) throw err;
if(results.length === 1) {
logger.info(iNameCopy + " does exist");
}
else if (results.length === 0){
logger.info(iNameCopy + " does not exist");
}
});
}());
}
Moving onto adding the if statement inside results.length === 1
for(var i=0; i<content.prices.length; i++) {
var price = content.prices[i].price
var itemName = content.prices[i].market_hash_name;
var q = "SELECT * FROM prices WHERE item = ?";
(function() {
var iNameCopy = itemName;
var priceCopy = price;
connection.query(q, iNameCopy, function (err, results) {
if (err) throw err;
if(results.length === 1) {
if(parseFloat(results[0].current_price) != parseFloat(priceCopy)) {
logger.info(iNameCopy + " does exist with old price: " + results[0].current_price + " and new price: " + priceCopy);
}
}
else if (results.length === 0){
logger.info(iNameCopy + " does not exist");
}
});
}());
}
Again this is still working.
Now finally replacing those loggers with new sql queries is where the code stumbles. The for loop runs as if I keep the loggers they display however the sql query loggers do not display:
I tried both this way I found from the other stack question and without wrapping it in a function but neither worked. Any suggestions?
for(var i=0; i<content.prices.length; i++) {
var price = content.prices[i].price
var itemName = content.prices[i].market_hash_name;
var q = "SELECT * FROM prices WHERE item = ?";
(function() {
var iNameCopy = itemName;
var priceCopy = price;
connection.query(q, iNameCopy, function (err, results) {
if (err) throw err;
if(results.length === 1) {
if(parseFloat(results[0].current_price) != parseFloat(priceCopy)) {
var sql2="UPDATE `prices` SET `current_price` = ?, `timeStamp` = ? WHERE `item` = ?";
(function() {
var iNameCopy2 = iNameCopy
var priceCopy2 = priceCopy
connection.query(sql2, [priceCopy2, 'Now()', iNameCopy2], function(err,results){
logger.info("UPDATE: " + iNameCopy2 + ' has been updated with price ' + priceCopy2);
});
}());
}
}
else if (results.length === 0){
var sql3="INSERT INTO `prices` (`item`, `current_price`, `timeStamp`) VALUES (?, ?, ?)";
(function() {
var iNameCopy3 = iNameCopy
var priceCopy3 = priceCopy
connection.query(sql3, [iNameCopy3, priceCopy3, 'Now()'], function(err,results){
logger.info("INSERT: " + iNameCopy3 + ' has been added with price ' + priceCopy3);
});
}());
}
});
}());
}
note: I have my database connection on the outside of the for loop:
var connection = mysql.createConnection(db_access);
connection.connect(function(err){
if(err){
logger.error('Error connecting to Db');
return;
}
});
I got a problem.I have multiple callback functions .
Function within function within a loop
I want to execute very first function fully first . Then I want to move further.
Currenlty no function is working fine:
function recurring_end() {
var diffbot = new Diffbot('ddddd');
var sql= "SELECT `bookmarks`.`id`,`bookmarks`.`bookmark_url` as url FROM bookmarks LIMIT 0, 10";
connection.query(sql, function(err,bookmarks) {
console.log(JSON.parse(JSON.stringify(bookmarks)));
for(var i = 0; i< bookmarks.length; i++){
(function(i) {
bookmark_id = bookmarks[i].id;
bookmark_url = bookmarks[i].url;
parseArticle(i,bookmark_id,bookmark_url,function(err,result){
bookamrk_title= result.bookmark_title;
bookmark_body= result.body;
bookmark_file_name= result.file_name;
preview_image = result.preview_image;
local_image_name = result.local_image_name;
mainPreviewImage = result.mainPreviewImage;
viewImage=result.viewImage;
var mediaExist =result.mediaExist;
if(mediaExist == 1) {
console.log("Entered in Media Exist");
download(preview_image, "images/" + local_image_name, function() {
console.log("Entered in download");
fs.exists("images/" + local_image_name, function(exists) {
console.log("Before Sending " +mainPreviewImage);
console.log("Before Sending Local " +local_image_name);
ImageMagic(local_image_name,mainPreviewImage,223,147,function(err,result) {
if(result != 0){
mainPreviewImage= result;
console.log("Image Magic Done" +mainPreviewImage);
AmazonUpload(mainPreviewImage,function(err,result) {
console.log("Amazon error "+err);
if(result != 0){
mainPreviewImage = result;
console.log("First Image Uploading is Sucessfully");
/* Now Lets Pass View Image FROM Graphic Magic */
ImageMagic(mainPreviewImage,viewImage,152,100,function(err,result) {
if(result != 0){
viewImage= result;
/* Upload New View File to Amazon */
AmazonUpload(viewImage,function(err,result) {
if(result != 0){
viewImage = result;
console.log("Second Image Upload to Amazon");
/*Finally here we need to write update logic here check it out */
console.log("Serious id is "+i);
console.log("Book Mark id " +bookmark_id);
console.log("bookamrk_title" +bookamrk_title);
console.log("preview_image"+mainPreviewImage);
console.log("viewImage"+viewImage);
console.log("End " +ddd);
}else {
/* need to write update Query here */
var viewImage="thumbnail_default_bookmark1.png";
}
});
}else{
/* need to write update Query here */
var viewImage="thumbnail_default_bookmark1.png";
}
});
}else {
/* need to writeUpdate Query Here */
var mainPreviewImage= 'default_bookmark.png';
var viewImage="thumbnail_default_bookmark1.png";
}
});
}else{
/* need to write Update Query here */
var mainPreviewImage= 'default_bookmark.png';
var viewImage="thumbnail_default_bookmark1.png";
}
});
});
});/* download function closed */
}
});
})(i);
}
console.log("Every Thing is done ");
});
}
function AmazonUpload(uploadImage,callback) {
knox.putFile('images/'+uploadImage,'BookmarkPreviewImages/'+uploadImage, {"Content-Type": "image/jpeg",'x-amz-acl': 'public-read'}, function (err, result) {
if(!err){
if(result.statusCode==200){
callback(err,uploadImage);
}else{
callback(err,0);
}
}else{
callback(err,0);
}
});
}
function download(uri, filename, callback) {
request.head(uri, function(err, res, body) {
//request(uri).pipe(fs.createWriteStream(filename),{end:true}).on('close', callback);
var r = request(uri);
r.pause()
r.on('response', function (resp) {
if(resp.statusCode === 200){
r.pipe(fs.createWriteStream(filename),{end:true}).on('close', callback); //pipe to where you want it to go
r.resume()
}
});
});
};
function ImageMagic(local_image_name,display_image,width,height,callback){
console.log("local_image_name is"+local_image_name);
gm('images/'+local_image_name).resize(width, height, '^').gravity('Center').crop(width, height).write('images/'+display_image, function (err) {
if(!err){
console.log("Sucessfully Image converted is "+display_image);
console.log("Sucessfully image which is converted "+ local_image_name);
callback(null,display_image);
}else{
console.log("Graphic Magic Error "+err);
callback(err,0);
}
});
}
function parseArticle(i,bookmark_id,bookmark_url,callback) {
diffbot.article({uri: bookmark_url}, function(err, response) {
var callBackString= {};
console.log("Diffbot Parsing URL with id " +bookmark_id+"and loop id is"+i);
var bookmark_title = response.title;
var body = response.html;
var timestamp = new Date().getTime().toString();
var file_name = common_function.generateRandomString() + timestamp + '.txt';
var timestamp0 = new Date().getTime().toString();
var local_image_name = common_function.generateRandomString() + timestamp0 + i + '.jpg';
var preview_image = response.media[0]['link'];
if(response.media[0].primary=='true'){
mainPreviewImage = "thumb_" + local_image_name;
viewImage = "thumbnail_" + local_image_name;
mediaExist=1;
}else{
mainPreviewImage="default_bookmark.png";
viewImage="thumbnail_default_bookmark1.png";
mediaExist=0;
}
callBackString .bookmark_title=bookmark_title;
callBackString.body = body;
callBackString.file_name = file_name;
callBackString.preview_image = preview_image;
callBackString.local_image_name = local_image_name;
callBackString.mainPreviewImage = mainPreviewImage;
callBackString.viewImage=viewImage;
callBackString.mediaExist =mediaExist;
callback(null,callBackString);
});
};
I understand the code is too long. I want to get an idea, I want to execute i=0 first completely, then I want to proceed further.
Any Idea how we can do in Nodejs. Any Help Will be appreicated
Thanks
Try replacing the loop with a recursive code like this..
function recurring_end() {
var diffbot = new Diffbot('ddddd');
var sql= "SELECT `bookmarks`.`id`,`bookmarks`.`bookmark_url` as url FROM bookmarks LIMIT 0, 10";
connection.query(sql, function(err,bookmarks) {
console.log(JSON.parse(JSON.stringify(bookmarks)));
var i = 0;
var callbackForParseArticle = function(err,result){
bookamrk_title= result.bookmark_title;
bookmark_body= result.body;
bookmark_file_name= result.file_name;
preview_image = result.preview_image;
local_image_name = result.local_image_name;
mainPreviewImage = result.mainPreviewImage;
viewImage=result.viewImage;
var mediaExist =result.mediaExist;
if(mediaExist == 1) {
console.log("Entered in Media Exist");
download(preview_image, "images/" + local_image_name, function() {
console.log("Entered in download");
fs.exists("images/" + local_image_name, function(exists) {
console.log("Before Sending " +mainPreviewImage);
console.log("Before Sending Local " +local_image_name);
ImageMagic(local_image_name,mainPreviewImage,223,147,function(err,result) {
if(result != 0){
mainPreviewImage= result;
console.log("Image Magic Done" +mainPreviewImage);
AmazonUpload(mainPreviewImage,function(err,result) {
console.log("Amazon error "+err);
if(result != 0){
mainPreviewImage = result;
console.log("First Image Uploading is Sucessfully");
/* Now Lets Pass View Image FROM Graphic Magic */
ImageMagic(mainPreviewImage,viewImage,152,100,function(err,result) {
if(result != 0){
viewImage= result;
/* Upload New View File to Amazon */
AmazonUpload(viewImage,function(err,result) {
if(result != 0){
viewImage = result;
console.log("Second Image Upload to Amazon");
/*Finally here we need to write update logic here check it out */
console.log("Serious id is "+i);
console.log("Book Mark id " +bookmark_id);
console.log("bookamrk_title" +bookamrk_title);
console.log("preview_image"+mainPreviewImage);
console.log("viewImage"+viewImage);
console.log("End " +ddd);
}else {
/* need to write update Query here */
var viewImage="thumbnail_default_bookmark1.png";
}
//additional lines to the end of the function
i++;
if (i<bookmarks.length){
bookmark_id = bookmarks[i].id;
bookmark_url = bookmarks[i].url;
parseArticle(i,bookmark_id,bookmark_url,callbackForParseArticle);
} else {
console.log("Every Thing is done ");
}
});
}else{
/* need to write update Query here */
var viewImage="thumbnail_default_bookmark1.png";
}
});
}else {
/* need to writeUpdate Query Here */
var mainPreviewImage= 'default_bookmark.png';
var viewImage="thumbnail_default_bookmark1.png";
}
});
}else{
/* need to write Update Query here */
var mainPreviewImage= 'default_bookmark.png';
var viewImage="thumbnail_default_bookmark1.png";
}
});
});
});/* download function closed */
}
};
if (bookmarks.length > 0){
parseArticle(i,bookmarks[i].id,bookmarks[i].url,callbackForParseArticle);
}
});
}
function AmazonUpload(uploadImage,callback) {
knox.putFile('images/'+uploadImage,'BookmarkPreviewImages/'+uploadImage, {"Content-Type": "image/jpeg",'x-amz-acl': 'public-read'}, function (err, result) {
if(!err){
if(result.statusCode==200){
callback(err,uploadImage);
}else{
callback(err,0);
}
}else{
callback(err,0);
}
});
}
function download(uri, filename, callback) {
request.head(uri, function(err, res, body) {
//request(uri).pipe(fs.createWriteStream(filename),{end:true}).on('close', callback);
var r = request(uri);
r.pause()
r.on('response', function (resp) {
if(resp.statusCode === 200){
r.pipe(fs.createWriteStream(filename),{end:true}).on('close', callback); //pipe to where you want it to go
r.resume()
}
});
});
};
function ImageMagic(local_image_name,display_image,width,height,callback){
console.log("local_image_name is"+local_image_name);
gm('images/'+local_image_name).resize(width, height, '^').gravity('Center').crop(width, height).write('images/'+display_image, function (err) {
if(!err){
console.log("Sucessfully Image converted is "+display_image);
console.log("Sucessfully image which is converted "+ local_image_name);
callback(null,display_image);
}else{
console.log("Graphic Magic Error "+err);
callback(err,0);
}
});
}
function parseArticle(i,bookmark_id,bookmark_url,callback) {
diffbot.article({uri: bookmark_url}, function(err, response) {
var callBackString= {};
console.log("Diffbot Parsing URL with id " +bookmark_id+"and loop id is"+i);
var bookmark_title = response.title;
var body = response.html;
var timestamp = new Date().getTime().toString();
var file_name = common_function.generateRandomString() + timestamp + '.txt';
var timestamp0 = new Date().getTime().toString();
var local_image_name = common_function.generateRandomString() + timestamp0 + i + '.jpg';
var preview_image = response.media[0]['link'];
if(response.media[0].primary=='true'){
mainPreviewImage = "thumb_" + local_image_name;
viewImage = "thumbnail_" + local_image_name;
mediaExist=1;
}else{
mainPreviewImage="default_bookmark.png";
viewImage="thumbnail_default_bookmark1.png";
mediaExist=0;
}
callBackString .bookmark_title=bookmark_title;
callBackString.body = body;
callBackString.file_name = file_name;
callBackString.preview_image = preview_image;
callBackString.local_image_name = local_image_name;
callBackString.mainPreviewImage = mainPreviewImage;
callBackString.viewImage=viewImage;
callBackString.mediaExist =mediaExist;
callback(null,callBackString);
});
};
Use async.js to manage your code flow
If you have multiple functions, func_1, func_2, func_3, that need to run in sequence, the code is
var async = require('async');
var functionList = [func_1, func_2, func_3];
async.series(functionList, function(err, result){
// results of func_1, func_2 and func_3
});