I'm using NodeJS and using the
tls.connect(port, host, options, callback)
To get my socket to write to. I pass it through a async.waterfall and the socket.writable property stays set to true and I can write to the socket throughout. However, if I try to use it with setTimeout, it ends up being closed. Is there a way to keep it open or is my syntax incorrect?
This is one of the calls in async waterfall:
function (sock, err, callback) {
console.log(sock.writable); // this is true
setTimeout(function(sock) {
console.log(sock.writable); // this is false but I'd like it to be true so I can use it for more logic
}, 3000, sock);
}
I've also tried
function (sock, err, callback) {
console.log(sock.writable); // this is true
var sockz = sock;
setTimeout(function() {
console.log(sockz.writable); // this is false but I'd like it to be true so I can use it for more logic
}, 3000);
}
and this
function (sock, err, callback) {
console.log(sock.writable); // this is true
setTimeout(function(sock) {
console.log(sock.writable); // this is false but I'd like it to be true so I can use it for more logic
}.bind(this, sock), 3000);
// callback(null, sock);
}], function (err, sock) {
console.log(sock.writable);
}
But all of them print false. Is my syntax incorrect or does the socket automatically close in this scenario where I'm trying to get it to wait?
Edit
Full async.waterfall:
async.waterfall([
// insert record into db
function (acb) {
dbConn.query()
.insert(tableName, ["HOST", "SERVER_NAME", "DATE_CREATED"], [hostname, "test", currentTime])
.execute(function (err, result) {
if (err) {
componentStatus.database = false;
// pass the error down to run all the functions
acb(null, sockz, componentStatus, err);
} else {
componentStatus.resultId = result.id;
acb(null, sockz, componentStatus, null);
}
});
},
// read record back
function (sockz, componentStatus, err, acb) {
if (componentStatus.resultId < 0) {
acb(null, sockz, componentStatus, err);
} else {
dbConn.query().select("ID").from(tableName).where("ID=?", [componentStatus.resultId]).execute(function (err, rows, cols) {
if (err) {
componentStatus.database = false;
acb(null, sockz, componentStatus, err);
} else {
acb(null, sockz, componentStatus, err);
}
});
}
},
// send message to rabbit
function (sockz, componentStatus, err, acb) {
sendStatusMessage(currentTime, componentStatus.resultId, function (err1, result) {
if (err1) {
componentStatus.messaging = false;
var error = err + ", " + err1;
acb(null, sockz, componentStatus, error);
} else {
console.log("rabbit timeout");
console.log(sockz.writable);
setTimeout(function(sockz) {
console.log("In timeout");
console.log(sockz.writable);
}.bind(this, sockz), 3000); // wait for 3s to check record was consumed
}
});
}
], function (err, sockz, componentStatus, actualError) {
console.log(sockz.writable);
});
}
});
};
exports.sendStatusMessage = function(dateCreated, id, callback) {
var notification = { "dateCreated": dateCreated, "id": id };
_sendMsg("test.queue", notification, {"contentType": "application/json"}, function (err, result) {
if (err) {
callback(err, null);
} else {
callback(null, result);
}
});
}
Related
the below function is generating the "x" is not a function error, for the love of me I have no idea why this is happening? any help is much appreciated.
function updateShareholder() {
var date = moment().format('MM/DD/YYYY');
console.log('updateShareholder');
var data = {
companyID: agreement.applicant.applicantCompanyID,
userID: agreement.coSigner.coSignerID,
agreementID: agreement.agreement.agreementID,
stock: agreement.stock.stock
}
company_worker.updateShareholder(data, function(err, result) {
if (err) {
console.log(err);
res.send(err);
} else {
console.log('updateShareholder');
process.nextTick(function() {
emailNotification()
});
}
});
};
if it helps here is the company worker function that is called within.
module.exports.updateShareHolder = function(req, callback) {
console.log('updateShareHolder');
Company.update({
"_id": req.companyID,
"shareHolders.userId": req.userID
}, {
$push: {
"shareHolders.$.agreements": {
agreementID: req.agreementID
}
}
}, {
$set: {
"shareHolders.$.shares": ++req.shares
}
},
function(err) {
if (err) {
console.log(err);
callback(err, err);
} else {
console.log('updateShareHolder');
callback(null, 'success');
}
})
};
and this is the function that calls the so-called broken function
function moveOn() {
if (addShareHolder == 'true') {
process.nextTick(function() {
addShareholder()
});
} else if (updateShareholder == 'true') {
process.nextTick(function() {
updateTheShareholder()
});
}
};
There's a typo in the function name.
You are exporting module.exports.updateShareHolder and calling company_worker.updateShareholder. Notice the lowercase h,
Let's say i need to constantly collecting some data from a lot of clients and in parallel running some complex loop that solving some stuff with this data. How can i do it? Should i just write this in my piece of code:
app.get('/', function(req, res) {
res.sendFile(__dirname + '/public/views/index0.html');
});
io.sockets.on('connection', function(socket) {
// SOME STUFF WITH THE SOCKET
socket.on('disconnect', function(data) {
//SOME OTHER STUFF
});
});
while(...) {
//THE LOOP STUFF
}
Or i need to use the setTimeout() and setInterval() functions? How can i do the loop on the server that runs in parallel with the callbacks' stuff?
Don’t use while for make it, this block a thread. setTimeout() will run only once. You need to use setInterval() function.
You can use the async module to handle the async operation with the callback or use promise to avoid callback.
Here how I handle a complex async for each operation, that might helpfull to you get idea handeling ayncs forach
var cond = { _schedule: schedule_id }; // find curse by schedule id
Course.find(cond, function (err, courses) {
if (err) {
callback({ "success": false, "message": "Not able to update" });
} else {
async.forEachLimit(courses, 1, function (course, coursesCallback) {
async.waterfall([
function (callback) {
var schedule_date = moment(change_data.date).format('YYYY-MM-DD') + "T00:00:00.000Z"
var Assignmentcond = {
assignment_schedule_order: {
$gte: schedule_date
},
_course: course._id,
_schedule: schedule_id,
_user: userid
};
Assignment.find(Assignmentcond)
.populate({
path: '_course',
})
.lean()
.sort({ assignment_schedule_order: 1 })
.exec(function (err, AssignmentList) {
if (err) {
callback(null, '');
} else {
//console.log("------------------AssignmentList---------------------------");
//console.log(AssignmentList);
async.forEachLimit(AssignmentList, 1, function (ThisAssignmentCell, ThisAssignmentCellCallback) {
async.waterfall([
function (callback) {
var SearchObj = items;
var lebelObject = {};
for (var i = 0, flag = 0, insert = 0; i < SearchObj.length; i++) {
if (SearchObj[i].date == ThisAssignmentCell.assignment_schedule_date) {
flag = 1;
}
if (flag == 1 && SearchObj[i].label != "") {
if (ThisAssignmentCell.day == SearchObj[i].day_index) {
insert = 1;
var lebelObject = SearchObj[i];
break;
}
}
}
callback(null, ThisAssignmentCell, lebelObject, insert);
},
function (ThisAssignmentCell, SearchObj, insert, callback) {
console.log('----------------------');
console.log('ThisAssignmentCell', ThisAssignmentCell);
console.log('SearchObj', SearchObj);
console.log('----------------------');
if (insert > 0) {
var query = { _id: ThisAssignmentCell._id },
fields = {
assignment_date: moment(SearchObj.date).format('MM/DD/YYYY'),
assignment_schedule_date: moment(SearchObj.date).format('YYYY-MM-DD'),
assignment_schedule_order: new Date(SearchObj.date),
day: SearchObj.day_index,
dayNum: SearchObj.weekday_num
},
options = { upsert: false };
Assignment.update(query, fields, options, function (err, affected) {
callback(null, '');
});
} else {
// var cond = { _id: ThisAssignmentCell._id};
// Assignment.remove(cond)
// .exec(function (err, cnt) {
// callback(null, '');
// });
}
}
], function (err, result) {
// result now equals 'done'
console.log('done')
ThisAssignmentCellCallback();
});
}, function (err) {
console.log("Assignment For Loop Completed");
callback(null, AssignmentList);
});
}
});
}
], function (err, result) {
// result now equals 'done'
console.log('done')
coursesCallback();
});
}, function (err) {
console.log("courses For Loop Completed");
});
}
});
Okay, so heres the full source of my function. All I want that the part that is surrounded by "////////////" would repeat. New function works too. I could have them both, very confused once I tried to pull the highlighted function into a new one and got loads of errors.
function reWebLogOn(steam, callback) {
steam.webLogOn(function(newCookie){
helper.msg('webLogOn ok');
cookies = newCookie;
offers.setup({
sessionID: currentSessionId,
webCookie: newCookie
}, function(){
if (typeof callback == "function") {
callback();
}
});
var steamcommunityMobileConfirmations = new SteamcommunityMobileConfirmations(
{
steamid: config.steamid,
identity_secret: config.identitySecret,
device_id: device_id,
webCookie: newCookie,
});
///////////////////////////////////////////////////////////////////////////////////////////////////////////
steamcommunityMobileConfirmations.FetchConfirmations((function (err, confirmations)
{
if (err)
{
console.log(err);
return;
}
console.log('steamcommunityMobileConfirmations.FetchConfirmations received ' + confirmations.length + ' confirmations');
if ( ! confirmations.length)
{
return;
}
steamcommunityMobileConfirmations.AcceptConfirmation(confirmations[0], (function (err, result)
{
if (err)
{
console.log(err);
return;
}
console.log('steamcommunityMobileConfirmations.AcceptConfirmation result: ' + result);
}).bind(this));
}).bind(this));
///////////////////////////////////////////////////////////////////////////////////////////////////////////
});
}
use timer's, an Interval would be handy
setInterval(function() {
//.. part that should be repleated
}, 30*1000);
window.setInterval() is your friend.
it executes a function at the provided interval of time.
for example, setInterval(()=>console.log("foo"),100) will log "foo" in the console every 100ms.
function reWebLogOn(steam, callback) {
steam.webLogOn(function(newCookie){
helper.msg('webLogOn ok');
cookies = newCookie;
offers.setup({
sessionID: currentSessionId,
webCookie: newCookie
}, function(){
if (typeof callback == "function") {
callback();
}
});
var steamcommunityMobileConfirmations = new SteamcommunityMobileConfirmations(
{
steamid: config.steamid,
identity_secret: config.identitySecret,
device_id: device_id,
webCookie: newCookie,
});
///////////////////////////////////////////////////////////////////////////////////////////////////////////
setInterval((function(){
steamcommunityMobileConfirmations.FetchConfirmations((function (err, confirmations){
if (err)
{
console.log(err);
return;
}
console.log('steamcommunityMobileConfirmations.FetchConfirmations received ' + confirmations.length + ' confirmations');
if ( ! confirmations.length)
{
return;
}
steamcommunityMobileConfirmations.AcceptConfirmation(confirmations[0], (function (err, result)
{
if (err)
{
console.log(err);
return;
}
console.log('steamcommunityMobileConfirmations.AcceptConfirmation result: ' + result);
}).bind(this));
}).bind(this));
}).bind(this),30000)
Put your code inside setInterval(function(){},1000) timer or do some recursive calls.
function(dataValue, cb) {
req.app.db.models.User.find({
_id: { $ne: dataValue._id }
}, function(err, totalUser) {
if (!err) {
var len = totalUser.length;
if (len !== 0) {
req.app.utility.async.map(totalUser, function(each, callback) {
console.log(each);
req.app.utility.async.mapSeries(each.nonregisterContact, function(element, callback1) {
console.log('element', element.number);
console.log('dataValue', dataValue.mobileNumber);
console.log('kolka', Number(element.number) === Number(dataValue.mobileNumber));
if (Number(element.number) === Number(dataValue.mobileNumber)) {
each.registerContact.push(dataValue._id.toString());
each.nonregisterContact.splice(element, 1);
each.save(function(err, finalResult) {
if (!err) {
} else {
console.log(err);
}
})
callback1(null, null);
} else {
callback1(null, null);
}
}, function(err, final) {
if (!err) {
callback(null, null);
} else {
console.log(err);
}
});
}, function(err, result) {
if (!err) {
console.log('2');
return cb(null, dataValue);
} else {
console.log(err);
}
});
} else {
return cb(null, dataValue);
}
} else {
cb(err);
}
})
}
I don't get any response after each.save method call in the mapSeries method final callback.I am trying this solution.How i will do the same thing. How I resolve that and handle this kind of situation?
I tried to simplify code, but I'm not sure that my code realizes your needs. Also I cann't test it :D
dataValue, each, element, finalResult are very common names, so you should use them with caution to keep code is readable/supportable.
// very bad idea is include other libraries to app
var async = require('async');
var db = require('db'); // this module must export connection to db
...
function (dataValue, cb) {
// processUser use data from closure of current function => inside of current
function processUser (user, callback) {
async.mapSeries(user.nonregisterContact, function(contact, callback){
// Check and exit if condition is not satisfied. It's more readable.
if (Number(contact.number) !== Number(dataValue.mobileNumber))
return callback(null); // ignore user
user.registerContact.push(dataValue._id.toString());
user.nonregisterContact.splice(contact, 1);
user.save(function(err, finalResult) { // Is finalResult ignore?
if (err)
console.log(err);
callback(); // ingnore error
})
}, callback);
db.models.User.find({_id: { $ne: dataValue._id }}, function(err, userList) {
if (!err)
return cb(err);
if (userList.length == 0)
return cb(new Error('Users not found'));
// use named function to avoid stairs of {}
async.map(userList, processUser, cb);
})
};
I'm in deep trouble trying to understand how to make my code asynchronous in Node.js land. Please see my code below, in two varieties.
Ok so here's my first try - I have three functions here. A processing function (iim), a file copy function (fse.copy), and an archive function (da).
I need da to happen after iim, and iim to happen after fse.copy.
This first approach results in archive happening, but it's empty because iim never appears to happen.
da(randomString, function(err) {
if (err) {
log.error(err);
} else {
fse.copy(temp_path, new_location + file_name, function(err) {
if (err) {
log.error(err);
} else {
log.info("File saved to " + new_location + file_name);
var sourceImage = new_location + file_name;
log.debug(sourceImage);
log.debug(randomString);
iim(sourceImage, randomString, function(err) {
if (err) {
log.error(err);
}
});
}
});
}
});
The next block is an alternate approach which results in the da happening before iim is finished.
fse.copy(temp_path, new_location + file_name, function(err) {
if (err) {
log.error(err);
} else {
log.info("File saved to " + new_location + file_name);
var sourceImage = new_location + file_name;
log.debug(sourceImage);
log.debug(randomString);
iim(sourceImage, randomString, function(err) {
if (err) {
log.error(err);
}
});
da(randomString, function(err) {
if (err) {
log.error(err);
}
});
}
});
Here's what I'd recommend -- in your question you say you need to essentially run three functions in series -- correct? Run function A, then function B, and lastly, run function C.
The simplest way to do this is using the asyncjs library.
Here's an example:
var async = require('async');
async.series([
function a(cb) {
// do stuff
cb();
},
function b(cb) {
// do stuff
cb();
},
function c(cb) {
// do stuff
cb();
},
], function() {
// this will run once all three functions above have finished
});
Now, let's say that each of those functions needs to return data to the next function. SO imagine that function B needs input from function A to run. How do you accomplish that? Using async.waterfall!
var async = require('async');
async.waterfall([
function a(cb) {
// do stuff
cb(null, 'value');
},
function b(val, cb) {
// do stuff with val
cb(null, 'woot');
},
function c(val, cb) {
// do stuff with val
cb(null);
},
], function() {
// this will run once all three functions above have finished
});
Not bad right?
Hope this helps!
EDIT: Here's a code block showing your code above refactored using asyncjs:
async.waterfall([
function(cb) {
fse.copy(temp_path, new_location + file_name, function(err) {
if (err) {
log.error(err);
} else {
log.info("File saved to " + new_location + file_name);
var sourceImage = new_location + file_name;
log.debug(sourceImage);
log.debug(randomString);
}
console.log('Finished running fs.copy');
cb(null, sourceImage, randomString);
});
},
function(sourceImage, randomString, cb) {
iim(sourceImage, randomString, function(err) {
if (err) {
log.error(err);
}
console.log('Finished running iim');
cb(null, randomString);
});
},
function(randomString, cb) {
da(randomString, function(err) {
if (err) {
log.error(err);
}
console.log('Finished running da');
cb();
});
}
], function() {
console.log('All done!');
});
So you can either put da into the callback for iim (right now it's not) from your second example:
fse.copy(temp_path, new_location + file_name, function(err) {
if (err) {
log.error(err);
} else {
log.info("File saved to " + new_location + file_name);
var sourceImage = new_location + file_name;
log.debug(sourceImage);
log.debug(randomString);
iim(sourceImage, randomString, function(err) {
if (err) {
log.error(err);
return;
}
da(randomString, function(err) {
if (err) {
log.error(err);
}
});
});
}
});
That said, callback depth can be flattened with the use of a library like async (https://github.com/caolan/async)