nodeJS - cant understand the behavior of the code - event-loop

function placeOrder(orderNo) {
console.log("Order is: " + orderNo);
setTimeout(deliver(orderNo),5000);
}
function deliver(orderNo) {
console.log("Item is delivered with Order No.- " + orderNo);
}
placeOrder(1);
placeOrder(2);
placeOrder(3);
placeOrder(4);
placeOrder(5);
placeOrder(6);
The above code is a nodejs code whose output should be:
order No:1
order No:2
order No:3
order No:4
order No:5
order No:6
Item is delivered with order No.- 1
Item is delivered with order No.- 2
Item is delivered with order No.- 3
Item is delivered with order No.- 4
Item is delivered with order No.- 5
Item is delivered with order No.- 6
But i am getting an output like this:
order No:1
Item is delivered with order No.- 1
order No:2
Item is delivered with order No.- 2
order No:3
Item is delivered with order No.- 3
order No:4
Item is delivered with order No.- 4
order No:5
Item is delivered with order No.- 5
order No:6
Item is delivered with order No.- 6
I am going wrong somewhere in my concept of single thread and asynchronous callbacks. Please someone explain me how the code is working.

Replace:
setTimeout(deliver(orderNo),5000);
}
with:
setTimeout(function() {
deliver(orderNo);
}, 5000);
The first parameter of the setTimeout function is a function pointer. In your code you were passing the result of the deliver(orderNo) call which is just some void parameter. Now you can get rid of the console.log inside your placeOrder function.

You use wrong setTimeout signature definition
var timeoutID = window.setTimeout(func, [delay, param1, param2, ...]);
var timeoutID = window.setTimeout(code, [delay]);
Hence, your code should be:
setTimeout(function() {
deliver(orderNo);
}, 5000);

tl;dr
This is a syntax issue. You are passing in the wrong argument type to setTimeout.
Change this:
setTimeout(deliver(orderNo),5000);
to this:
setTimeout(deliver, 5000, orderNo);
Be wary that this syntax does not work in IE 9 or below.
Explanation
If you look at the documentation for setTimeout on MDN, you will see that the first argument is either a Function or a String consisting of JavaScript code. In your case, you are trying to pass in a function which accepts this syntax:
setTimeout(func, [delay, param1, param2, ...]);
Where param1, param2, ... are the arguments for your function, func. What you are doing is passing in the value returned by the function rather than the function itself.
Since you are passing a value, setTimeout does not execute as expected. The reason you are still getting an output from deliver is because it is actually being executed at runtime rather than by setTimeout. It's almost the same thing as calling deliver by itself.
Functions as Arguments
Remember that functions are First-Class Citizens in JavaScript, which means they can be passed into function as arguments.
Bonus
There are a few alternative syntaxes you can use.
String
As pokeybit mentioned in the comments:
setTimeout("deliver("+orderNo+");",5000);
Which allows you to use the function and it's parameters at once. However, this is an uglier syntax due to the string concatenation.
Anonymous Function
Use setTimeout with an anonymous function:
setTimeout(function() {
console.log("Item is delivered with Order No.- " + orderNo);
}, 5000);
This is arguably the most common and safest syntax.
Function that returns an anonymous function
You can keep:
setTimeout(deliver(orderNo),5000);
If you define deliver as a function that returns a Function:
function deliver(orderNo) {
return function() {
console.log("Item is delivered with Order No.- " + orderNo);
}
}
Since this value returns a function, it is the proper type for setTimeout.

Related

JIKAN API - import data with dynamic ID

I am trying to use this for my import with WPAI in Wordpress. But as a non-developer I have problem to find out, how the "my_get_id" function should looks like.
My first function looks like this
function get_dynamic_import_url() { $id = my_get_id(); return sprintf( "https://api.wordpress.org/plugins/info/1.2/?action=query_plugins&request[page]=%s&request[per_page]=400", $id ); }
and my "my_get_id" like this
function my_get_id($opt = ""){ $ids = array(1,2,3); return($ids); }
however "my_get_id" is wrong, because it does not return single ID, but an array.
the ID is from 1 - 221
Any idea where should I look, for such a function with return only one ID after another.
Is it possible to implement Rate Limiting- Per Second | 3 requests, otherwise I get 404
thank you for any hint.
regards

How can I save part of a string in an alias using Cypress?

I'm trying to save just a number from a string I get from a paragraph but when I try to asign an alias to it and then check the value it returns undefined. I've tried a few solutions I found but none of those seem to work for me. These are two ways I tried (I tried another one similar to the second one but using split, had same result). The console.log inside of the 'then' doesn't show in the console, and when I try the alias after the code is when I get undefined.
cy.get('p')
.eq(1)
.should('have.text', '/[0-9]+/g')
.as('solNumber')
cy.get('p')
.eq(1)
.invoke('text')
.then((text)=>{
var fullText = text;
var pattern = /[0-9]+/g;
var number = fullText.match(pattern);
console.log(number);
})
.as('solNumber')
Please convert with + operator and return the numeric value if you want numeric type to be stored.
cy.get('p').eq(1)
.invoke('text')
.then(fullText => {
const number = fullText.match(/[0-9]+/);
return +number // text to numeric
})
.as('solNumber')
cy.get('#solNumber')
.should('eq', 42) // numeric type
});
Running your 2nd code on this,
<p>21</p>
<p>42</p>
gives the correct outcome
cy.get('p')
.eq(1)
.invoke('text')
.then((text)=>{
var fullText = text;
var pattern = /[0-9]+/g;
var number = fullText.match(pattern);
console.log(number); // logs 42
})
.as('solNumber')
cy.get('#solNumber')
.should('eq', '42') // passes
So, you need to inspect the DOM, it looks like it's not what you expect.
The first attempt you were passing a jquery element to the .should() and although some chainers change the subject yours did not so it saved the jquery element as solNumber.
The second attempt invokes the .text() which was passed to the .then() it logs the number correctly. However, you did not return anything at the end of the .then() block, therefore, solNumber should hold the entire paragraph.
This should help you out to extract the specific number and save it as an alias.
cy.get('p')
.invoke('text')
.invoke('trim')
.then(paragraph => {
const matcher = /some/
expect(paragraph).to.match(matcher) // check number is there
const indexOfText = paragraph.match(matcher) // get index of match text
return paragraph.substring(indexOfText.index, indexOfText.index + indexOfText[0].length) // return substring
})
.as('savedText')
cy.get('#savedText')
.then(cy.log) // will print out the number you seek

VueJS: Sum up computed values to one computed value

I have a html form and based on the user input I want to give a total score of completion (e.g 80%).
My plan is to do that with computed values that are watching seperate parts of the form and for the total score I want to sum them up like so:
simplified version of the vue file:
[..]
computed: {
Chk_input1: function(){
// Here will be a check if at least 4 characters in input field, if yes
return 30
},
Chk_input2: function(){
// Here will be a check if multiple conditions are met, if yes
return 30
},
Chk_input3: function(){
// Here will be a check if at least 4 characters in input field, if yes
return 26
},
total_score: function(Chk_input1, Chk_input2, Chk_input3){
// finally sum up the computed values input1 - input3
return Chk_input1 + Chk_input2 + Chk_input3
}
},
But the result is:
total_score = [object Object]undefinedundefined%
How do I sum up these values properly?
Wherever you're calling total_score, you're passing an object for the first argument, and undefined to the second two.
total_score should be written like this:
total_score: function() {
return this.Chk_input1 + this.Chk_input2 + this.Chk_input3
}
The difference between my code and yours is that my code is accessing the other computed properties to return a sum, and yours is accepting arguments, which it accesses to calculate the sum.

"update" query - error invalid input synatx for integer: "{39}" - postgresql

I'm using node js 0.10.12 to perform querys to postgreSQL 9.1.
I get the error error invalid input synatx for integer: "{39}" (39 is an example number) when I try to perform an update query
I cannot see what is going wrong. Any advise?
Here is my code (snippets) in the front-end
//this is global
var gid=0;
//set websockets to search - works fine
var sd = new WebSocket("ws://localhost:0000");
sd.onmessage = function (evt)
{
//get data, parse it, because there is more than one vars, pass id to gid
var received_msg = evt.data;
var packet = JSON.parse(received_msg);
var tid = packet['tid'];
gid=tid;
}
//when user clicks button, set websockets to send id and other data, to perform update query
var sa = new WebSocket("ws://localhost:0000");
sa.onopen = function(){
sa.send(JSON.stringify({
command:'typesave',
indi:gid,
name:document.getElementById("typename").value,
}));
sa.onmessage = function (evt) {
alert("Saved");
sa.close;
gid=0;//make gid 0 again, for re-use
}
And the back -end (query)
var query=client.query("UPDATE type SET t_name=$1,t_color=$2 WHERE t_id = $3 ",[name, color, indi])
query.on("row", function (row, result) {
result.addRow(row);
});
query.on("end", function (result) {
connection.send("o");
client.end();
});
Why this not work and the number does not get recognized?
Thanks in advance
As one would expect from the initial problem, your database driver is sending in an integer array of one member into a field for an integer. PostgreSQL rightly rejects the data and return an error. '{39}' in PostgreSQL terms is exactly equivalent to ARRAY[39] using an array constructor and [39] in JSON.
Now, obviously you can just change your query call to pull the first item out of the JSON array. and send that instead of the whole array, but I would be worried about what happens if things change and you get multiple values. You may want to look at separating that logic out for this data structure.

Rally Analytics set the startindex for a query

I have a query for the Rally Analytics which returns a data set larger than the pagesize. So I want to do another query to return the remainder data set. I tried setting a startindex value but that does not work, StartIndex stays at 0.
this.query = {
find:Ext.encode(requestedQuery.find),
StartIndex:20000,
pagesize:20000 //MAX_PAGESIZE
};
_queryAnalyticsApi:function () {
Ext.Ajax.request({
url:"https://rally1.rallydev.com/analytics/1.27/" + this.workspace + "/artifact/snapshot/query.js?" + Ext.Object.toQueryString(this.query) +
"&fields=" + JSON.stringify(this.requestedFields) + "&sort={_ValidFrom:1}",
method:"GET",
//need to change this to a POST
success:function (response) {
this._afterQueryReturned(JSON.parse(response.responseText));
},
scope:this
});
},
that works, it was confusing because the attribute of the result set is called StartIndex. It would be nice if the granularity (i.e. day, week) could be defined and handled on the server first, so it wouldn't have to return such a large dataset.
The parameter you'll want to use is called start. Also, on subsequent pages it is important to include a filter using the ETLDate returned from the first page of data so your results are consistent in time. We have created a SnapshotStore in the AppSDK 2.0 that handles all this complexity for you. Look for it soon!