This question already has answers here:
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
Iterate array and wait for promises
(1 answer)
Closed 4 years ago.
While I have been working in python for quite some time, I've recently started working with javascript for its tight integration with Web.
I am still struggling with concepts of event driven programming and promise driven function.
Anyway, Below I am using node.js module is-port-reachable.
It does a good job of returning status if given host is reachable over a given port or not.
However, I need to collect combined info of host and port status.
For e.g. if I have hosts = ['hostA' , 'hostB' ];
I need to collect status of its port scan status as
hosts2 = [ ('hostA' , true) , ('hostB', false)];
With below code, I am able to get individual status of port scan for each host, but when I try to add it to array host2, its coming back as empty.
It seems promise function is not able to take/recognize external variable aHost.
const isPortReachable = require('is-port-reachable');
hosts = [ 'host' , 'host2'];
var hosts2 = new Array();
for ( var l = 0; l < hosts.length; l++) {
var aHost = hosts[l];
const myFunction = (aHost) =>{
return isPortReachable(8443, {host: aHost})
};
myFunction(aHost).then(result => {
console.log(aHost, result);
hosts2.push((aHost,result));
});
}
console.log(hosts2);
Output:
Further, Looks like console.log(hosts2); is getting executed before for loop.
node myscript.js
[]
hostA true
hostB false
Any help is appreciated.
Related
This question already has answers here:
Capturing javascript console.log? [duplicate]
(2 answers)
Closed 4 years ago.
I have been seeing in some questions on Stack Overflow that there is examples, example code or snippets. Such as the one below:
console.log(1, 2, 3)
By running the code snippet above you'll see something like this:
I am currently working with something in node.js that also requires to fetch the output from console.logs. I find it fascinating that Stack Overflow is able to do this, whilst I don't even have a single clue how they did this.
I would be very thankful if someone could send me a link to where I can read and learn about how to fetch data form the console API.
Cheers,
Richard
P.S. If someone could edit this post to display the image, I'd be very thankful.
Edit
The project that I'm working on is an Electron app. It uses both the node.js process and the Electron BrowserWindow.
It uses a logger that I'm working on wich needs to fetch data from console.log
Some of the use cases might look like this:
console.log('%d is cool', User.firstName)
// => "Jason is cool"
or
console.log('User ID:', User._id)
// => A5FFE
or
console.log('%cUser connected!', 'color: #00FF00')
// => User connected!
// In green text.
You can overwrite window.console.log with your own function to achieve such an effect. For example:
const oldConsoleLog = console.log.bind(console);
console.log = (...params) => {
const textToDisplay = params.map(param =>
typeof param === 'object'
? JSON.stringify(param)
: param
);
document.body.appendChild(document.createElement('div'))
.textContent = textToDisplay;
oldConsoleLog(...params);
};
console.log('foo');
console.log('bar baz');
console.log({ prop: 'value' });
.as-console-wrapper {
height: 60%
}
In nodejs, console.log just formats the data you pass to it and then writes it to process.stdout which is a stream that goes to your commandline window. To intercept that, you can just listen for events on that stream:
process.stdout.on("data", chunk => {
// Do what you wanna do
});
I am using the Zapier Code application in the javascript language, I am making a request in an api but in almost all attempts at the time of executing the script, I get the error message: "We had trouble sending your test through. Please try again. Error:
2018-03-09T14:32:54.748Z c0958e0a-23a6-11e8-9be1-a515bc24f853 Task timed out after 1.00 seconds". Sometimes script execution happens successfully, but most of the time it gives this error.
The calling code in the api I'm using is this:
var promises = [];
var retornoDaChamada;
promises.push(fetch(urls));
Promise.all(promises).then(function(res){
var blobPromises = [];
for (var i = res.length - 1; i >= 0; i--) {
blobPromises.push(res[i].text());
}
return Promise.all(blobPromises);
}).then(function(body){
retornoDaChamada=JSON.parse(body);
var titulosDaApi = [retornoDaChamada.length];
var duracao = [retornoDaChamada.length];
var ids = [retornoDaChamada.length];
for(var i=0; i<retornoDaChamada.length; i++){
titulosDaApi[i]=retornoDaChamada[i].title;
duracao[i]=milissegundosParaHorasMinutosSegundos(retornoDaChamada[i].files[0].fileInfo.duration);
ids[i]=retornoDaChamada[i].id;
}
var output = {titulosDaApi, duracao, ids};
callback(null, output);
}).catch(callback);
I read the documentation of the application Code and I kind of understood that free user only has the time of up to 1 second for calls in Api, is there any way I can get around this problem even though I am a free user?
David here, from the Zapier Platform team.
It's a little tough to understand the context of your code, but it looks like you're doing multiple HTTP requests. Due to their nature, they're a very slow operation. If you're doing more than 1 (maybe two if the external resource responds really quickly), you're unlikely to be able to fit everything into 1 second.
Sorry for the bad news!
I am trying to parallelize a JavaScript project using parallel.js, but I am running into some kind of parsing problems.
The goal of the project is to have 9 ticket-sellers process customers in parallel. We have a working code right now, but the processing of the customers is still asynchronous, and we are trying to achieve the parallelization part using parallel.js.
My original code in JS before parallelizing is:
var ticketers = ["H", "M1", "M2", ...]; //There are 9 ticket-sellers
for(var i = 0; i < ticketers.length; i++) {
ticketerBehavior(i);
}
Where ticketers are the 9 ticket-sellers, and ticketerBehavior() is the function that takes care of what happens when a ticket-seller receives a customer.
Using the parallel.js documentation and examples, this is what we tried out:
var ticketBehav = function(ticketers){
for (var i = 0; i < ticketers.length; i++)
ticketerBehavior(i);
};
var p = new Parallel(100);
p.spawn(ticketBehav(ticketers)).then(console.log(ticketBehav(ticketers)));
However, when we run the program, it gives us this error:
/home/user/node_modules/paralleljs/lib/parallel.js:106
return preStr + 'process.on("message", function(e) {process.send(JSON.stringify((' + cb.toString() + ')(JSON.parse(e).data)))})';
^
TypeError: Cannot read property 'toString' of undefined
at Parallel.getWorkerSource (/home/user/node_modules/paralleljs/lib/parallel.js:106:91)
I tried googling the error but it does not return any results so far. I was a little confused on how to troubleshoot this error, since our data is technically serializable as JSON since they are only strings. Would a version compatibility cause any issues with running parallel.js as well?
Could anyone please advise me on where to start troubleshooting? Any tips/advice would be appreciated. Thank you!
Try this:
Pass your ticketers
For each ticket execute your function
Then return your data
p.spawn(function (ticketers) {return ticketBehav(data)}).then(function(data){ console.log(data) });
In my current project, we have a HTML page. In HTML page, we have several buttons, for instance we have buttons for Temperature Sensor, Humidity Sensor, Alarm etc. When we click on a button than in back-end it will run corresponding Node.js file, for instance when we click on Temperature sensor button than it will run TemperatureSensor.js file located in the same path. The code for HTML page is as shown below:
The code of TemperatureSensor.js is as below:
var mqtt = require('mqtt');
var client = mqtt.connect('mqtt://test.mosquitto.org:1883');
var NUM_SAMPLE_FOR_AVG = 5;
var numSample = 0;
var tempCelcius = 0;
var currentAvg = 0;
client.subscribe('tempMeasurement');
client.on('message', function(topic, payload) {
if (topic.toString() == "tempMeasurement") {
sensorMeasurement = JSON.parse(payload);
console.log("tempValue is " + sensorMeasurement.tempValue);
if (numSample <= NUM_SAMPLE_FOR_AVG) {
numSample = numSample + 1;
if (sensorMeasurement.unitOfMeasurement == 'F') {
tempCelcius = ((sensorMeasurement.tempValue - 32) * (5 / 9));
} else {
tempCelcius = sensorMeasurement.tempValue;
}
currentAvg = parseFloat(currentAvg) + parseFloat(tempCelcius);
if (numSample == NUM_SAMPLE_FOR_AVG) {
currentAvg = currentAvg / NUM_SAMPLE_FOR_AVG;
var avgTemp = {
"tempValue" : parseFloat(currentAvg),
"unitOfMeasurement" : sensorMeasurement.unitOfMeasurement
};
client.publish('roomAvgTempMeasurement', JSON
.stringify(avgTemp));
console.log("Publishing Data roomAvgTempMeasurement ");
numSample = 0;
currentAvg = 0;
}
}
}
});
The problem is when we clicked on TemperatureSensor button in browser than it display error: TemperatureSensor.js:1 Uncaught ReferenceError: require is not defined. if the content of TemeperatureSensor is console.log("Hello") than it displays Hello in the console of browser. How to provide dependency ??Why we need to do this bcoz if we want to run TemperatureSensor, HumiditySensor etc. than we need to run these in terminal, for instance if we want to run TemperatureSensor than in terminal we have to write sudo node TempeatureSensor.js. This require more manual efforts so in order to reduce this effort we need such kind of HTML page. How to resolve the about problem ??
You can't run Node.js code in the browser, they're completely separate environments (for example, browsers do not have the require function, hence why you're getting that error). Your best bet is to look into creating a REST service of some kind (using Express, Hapi or Restify, most likely) that will allow you to call a Node.js server through HTTP.
This is a decent introduction to the topic - it uses MongoDB for data persistence, but this is in no way a requirement when it comes to making stuff like this. In your case, you'll basically just have to define a route for Temp and Humidity, run your code to get the data in the route handler, and then send JSON data back on the response object. You'll then be able to use jQuery (or any number of other libraries) to make AJAX requests to these routes.
EDIT: After looking at the MQTT GitHub page, there is another option - the library can be used in the browser if bundled using a tool like Browserify or Webpack. Given the complexities of learning to write and maintain REST services, this may well be a better option.
This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 6 years ago.
I'm sure my problem is based on a lack of understanding of asynch programming in node.js but here goes.
For example: I have a list of links I want to crawl. When each asynch request returns I want to know which URL it is for. But, presumably because of race conditions, each request returns with the URL set to the last value in the list.
var links = ['http://google.com', 'http://yahoo.com'];
for (link in links) {
var url = links[link];
require('request')(url, function() {
console.log(url);
});
}
Expected output:
http://google.com
http://yahoo.com
Actual output:
http://yahoo.com
http://yahoo.com
So my question is either:
How do I pass url (by value) to the call back function? OR
What is the proper way of chaining the HTTP requests so they run sequentially? OR
Something else I'm missing?
PS: For 1. I don't want a solution which examines the callback's parameters but a general way of a callback knowing about variables 'from above'.
Your url variable is not scoped to the for loop as JavaScript only supports global and function scoping. So you need to create a function scope for your request call to capture the url value in each iteration of the loop by using an immediate function:
var links = ['http://google.com', 'http://yahoo.com'];
for (link in links) {
(function(url) {
require('request')(url, function() {
console.log(url);
});
})(links[link]);
}
BTW, embedding a require in the middle of loop isn't good practice. It should probably be re-written as:
var request = require('request');
var links = ['http://google.com', 'http://yahoo.com'];
for (link in links) {
(function(url) {
request(url, function() {
console.log(url);
});
})(links[link]);
}
Check this blog out. A variable can be passed by using .bind() method. In your case it would be like this:
var links = ['http://google.com', 'http://yahoo.com'];
for (link in links) {
var url = links[link];
require('request')(url, function() {
console.log(this.urlAsy);
}.bind({urlAsy:url}));
}
See https://stackoverflow.com/a/11747331/243639 for a general discussion of this issue.
I'd suggest something like
var links = ['http://google.com', 'http://yahoo.com'];
function createCallback(_url) {
return function() {
console.log(_url);
}
};
for (link in links) {
var url = links[link];
require('request')(url, createCallback(url));
}