waitForSelector timeout option doesn't work - javascript

I keep trying to use a variable as the timeout value but it never seems to work.
var b = data1.raw_time.split(' ');
console.log(b[1]);
let time = parseInt(b[1], 10) * 60000;
console.log(time);
message.channel.send('Server is in queue for ' + b[1] + ' minutes!');
try {
await page.waitForSelector('.main #confirm', { timeout: time });
await page.click('.main #confirm');
} catch (error) {
message.channel.send('Server start sequence was aborted');
}
}
Am I doing something wrong ?

Related

If check / check if property exists not working

I have been trying to make a debounce system that is ID based using unix timestamp i want it to print passed if it hasn't been called at all in the past second if it has print failed(with that specific id)
I can't figure out what exactly is going wrong i've tried everything I can imagine
I have recreated the problem in a testfile i've pasted the code below
const Cooldowns = {}
function Test(ID) {
const CurrentDate = Date.now();
let IsReal = false;
if (Cooldowns[ID]) {
IsReal = true;
};
console.log(Cooldowns[ID])
console.log(IsReal)
if (Cooldowns[ID] < CurrentDate || !(IsReal)) {
Cooldowns[ID] = CurrentDate + 1;
console.log(ID + " Time " + CurrentDate + " Passed");
} else {
console.log(ID + " Time " + CurrentDate + " Failed");
};
}
Test(12);
Test(19);
setTimeout(() => {
console.log("----------------------------------------------------");
Test(12);
Test(19);
Test(2);
setTimeout(() => {
console.log("-----------------------------------------------------");
Test(12);
Test(19);
Test(2);
}, 500);
}, 1050);

javascript set interval time every 3 sec for first 6 seconds, then 5 seconds continuously till i receive the answer

I want to ping a server for response every 3 seconds for the first 6 seconds, after that I want to increase the interval time to 5 seconds till i get the response. I did the first part, I'm trying to solve the next 5 seconds ping
var firstPing = 3000,
pingStop = 6000,
pingForever = 5000;
var ping = setInterval(function() { execute() }, firstPing);
setTimeout(function() {clearInterval(ping)}, pingStop);
setInterval(function() {execute()}, pingForever);
function execute() {
console.log('hello: ' + new Date().getSeconds());
// After successful response, clearInterval();
}
Might it be simpler to just call execute() every 1 second and only have execute do something when an incrementing counter variable is a certain value?
var ping = setInterval(function() { execute() }, 1000);
let v = 0;
function execute() {
v++;
if(v==3 || v==6 || (v>6 && v%5 == 1))
console.log('hello: ' + new Date().getSeconds());
// After successful response, clearInterval();
`
Here is something that manages the transition of the ping from 3 to 5 secs.
const firstPing = 3000,
pingStop = 6000,
pingForever = 5000;
let currentPing = 0;
let ping = setInterval(function() { execute() }, firstPing);
function execute() {
console.log('hello: ' + new Date().getSeconds());
// After successful response, clearInterval();
if(++currentPing >= 2 ) {
clearInterval(ping);
ping = setInterval(() => execute(), pingForever);
}
}
You can use count variable, you have firstPing of 3sec. Instead of clearing the interval you can update the firstPing with pingForever.
var firstPing = 3000,
pingStop = 6000,
pingForever = 5000;
let count = 0;
var ping = setInterval(() => {
execute();
firstPing = (count === 2) ? pingForever : firstPing;
count++;
console.log(count, firstPing);
}, firstPing);
function execute() {
// console.log('hello: ' + new Date().getSeconds());
}
I would just use setTimeout for simplicity.
var found = null;
function tryRequest() {
if (found) return;
// send request
// in successful response, set 'found' to 'true'
setTimeout(tryRequest, found == null ? 3000 : 5000);
found = false;
}
setTimeout(tryRequest, 3000);

Firebase clearTimeout not stop the setTimeout

How can I stop a setTimeout function before starting from the onWrite event on a "Firebase Cloud Function"? I try with setTimeout, but the clearTimeout do not stop the setTimeout.
P.S.: I've already raised the script timeout from the Firebase panel from 60 seconds (default) to 360 seconds.
var timeOutOnline = {};
exports.online = functions.database.ref('/server/{serverId}/online/time').onWrite(event => {
const serverId = event.params.serverId;
var time = event.data.val();
var lastDateOnline = new Date( time * 1000);
var dateString = lastDateOnline.toGMTString();
clearTimeout(timeOutOnline[serverId]);
refGet = db.ref('/server/'+serverId+'/online/');
refGet.once('value').then(function(snapshot) {
var onlineSnap = snapshot.val();
if (onlineSnap && onlineSnap.alarm == true) {
sendMail(serverId,false, 'not responding' , 'Server '+ serverId + ' not responding from '+dateString);
setAlarmStatus(serverId,false);
} else {
timeOutOnline[serverId] = setTimeout(function() {
sendMail(serverId,true, 'not responding' , 'Server '+ serverId + ' not responding from '+dateString);
setAlarmStatus(serverId,true);
}, 21000);
}
});
return true;
});
UPDATE:
Now I use promise, but clearTimeout still not working, not clearing setTimeout function. What am I doing wrong?
var timeOutOnline = {};
exports.online = functions.database.ref('/server/{serverId}/online/time').onWrite(event => {
const serverId = event.params.serverId;
var time = event.data.val();
var lastDateOnline = new Date( time * 1000);
var dateString = lastDateOnline.toGMTString();
console.log(v);
if(!timeOutOnline[serverId]) {
timeOutOnline[serverId] = [];
} else {
timeOutOnline[serverId].length;
for (var i = 0; i < timeOutOnline[serverId].length; i++) {
if (timeOutOnline[serverId][i]) {
timeOutOnline[serverId][i].cancel();
timeOutOnline[serverId][i] = null;
}
}
}
timeOutOnline[serverId] = timeOutOnline[serverId].filter(n => n);
refGet = db.ref('/server/'+serverId+'/online/');
refGet.once('value').then(function(snapshot) {
var onlineSnap = snapshot.val();
if (onlineSnap && onlineSnap.alarm == true) {
sendMail(serverId,false, 'not responding' , 'Server '+ serverId + ' not responding from '+dateString);
setAlarmStatus(serverId,false);
} else {
timeOutOnline[serverId].push(waitForServer(210000));
var index = timeOutOnline[serverId].length - 1;
return timeOutOnline[serverId][index].promise.then(function(i) {
console.log('Server '+ serverId + ' not responding from '+dateString);
sendMail(serverId,true, 'not responding' , 'Server '+ serverId + ' not responding from '+dateString);
setAlarmStatus(serverId,true);
});
}
});
return true;
});
function waitForServer(ms) {
var timeout, promise;
promise = new Promise(function(resolve, reject) {
timeout = setTimeout(function() {
resolve('timeout done');
}, ms);
});
return {
promise:promise,
cancel:function(){
console.log('cancel timeout: '+timeout);
clearTimeout(timeout);
}
};
}
There's a lot of things wrong in this function.
First of all, it's not clear to me why you want to use setTimeout() in this function. In fact, there are almost no valid use cases for setTimeout() with Cloud Functions. Functions are supposed to execute as fast as possible, and setTimeout only really just incurs extra cost to your processing. Cloud Functions does not enable you to run "background work" that survives past the invocation of the function - that's just not how it works.
Second of all, you're performing async work here, but you're not returning a promise to indicate when that work completes. If you don't return a promise that's resolved when your work completes, your function is highly likely to exhibit strange problems, including work not completing as you'd expect.

html not updating until the end of an ajax function

I'm trying to write a 3 second countdown function in JavaScript. The start of the countdown is set by the server so I have setInterval function which calls an ajax function which runs a script on the server to see if it is ready to start the countdown. If the countdown is set, the data returned is that the countdown is ready and will start in a specified number of milliseconds.
I've got the following function which, if I step through I can see the screen updating step by step. However, when I simply run the script it updates everything in bulk. I do not understand why?
$.ajax({
url : "/check_countdown/", // the endpoint
type : "GET", // http method
data : { info : info }, // data sent with the post request
// handle a successful response
success : function(json) {
console.log(json);
if (json.ready == 'True') {
// if we have a start_time then we get ready for the count down
console.log("Countdown ready to start!"); // sanity check
// stop pinging the server
clearInterval(countdownInterval);
// clear screen
$('#holdingImage').hide();
// show countdown block
$('#countdownText').show();
startTime = new Date().getTime() + json.milliseconds;
nowTime = new Date().getTime();
console.log("Every ", nowTime, startTime);
while (nowTime < startTime) {
nowTime = new Date().getTime();
}
$('#countdownText').html("<h1>Three</h1>");
startTime = startTime + 1000;
console.log("Second ", nowTime, startTime);
while (nowTime < startTime) {
nowTime = new Date().getTime();
}
$('#countdownText').html("<h1>Two</h1>");
startTime = startTime + 1000;
console.log("Counts ", nowTime, startTime);
while (nowTime < startTime) {
nowTime = new Date().getTime();
}
$('#countdownText').html("<h1>One</h1>");
} else {
console.log("Countdown NOT ready to start!"); // another sanity check
}
},
// handle a non-successful response
error : function(xhr,errmsg,err) {
$('#results').html("<div class='alert-box alert radius' data-alert>Oops! We have encountered an error: "+errmsg+
" <a href='#' class='close'>×</a></div>"); // add the error to the dom
console.log(xhr.status + ": " + xhr.responseText); // provide a bit more info about the error to the console
}
});
I figure a second (1000 milliseconds) between updates should be enough?
$.ajax({
url : "/check_countdown/", // the endpoint
type : "GET", // http method
data : { info : info }, // data sent with the post request
async: false, //<---- Add this
....
only Add (async: false)
This is the solution that I came up with. I'm not convinced by its efficacy but ...
I changed the success function to:
success : function(json) {
console.log(json);
if (json.ready == 'True') {
// if we have a start_time then we get ready for the count down
console.log("Countdown ready to start!"); // sanity check
console.log(json);
// stop pinging the server
clearInterval(countdownInterval);
// clear screen
$('#holdingImage').hide();
// show countdown block
$('#countdownText').show();
startTime = new Date().getTime() + json.milliseconds;
nowTime = new Date().getTime();
while (nowTime < startTime) {
nowTime = new Date().getTime();
}
startCountdown();
}
I added a new function called startCountdown() which is:
function startCountdown () {
var display1 = document.querySelector('#countdownText'),
startTime = 5,
remainingTime = startTime,
timer = new CountDownTimer(startTime);
timer.onTick(format1).start();
function format1(minutes, seconds) {
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
display1.textContent = seconds;
remainingTime = parseInt(minutes) * 60 + parseInt(seconds);
if ((minutes=="00") && (seconds=="00")){
console.log("time expired!"); // sanity check
}
}
}
And then I used this timer.js script which I had from elsewhere (I do not know where I got it so cannot credit the author - sorry)
function CountDownTimer(duration, granularity) {
this.duration = duration;
this.granularity = granularity || 1000;
this.tickFtns = [];
this.running = false;
}
CountDownTimer.prototype.start = function() {
if (this.running) {
return;
}
this.running = true;
var start = Date.now(),
that = this,
diff, obj;
(function timer() {
diff = that.duration - (((Date.now() - start) / 1000) | 0);
if (diff > 0) {
setTimeout(timer, that.granularity);
} else {
diff = 0;
that.running = false;
}
obj = CountDownTimer.parse(diff);
that.tickFtns.forEach(function(ftn) {
ftn.call(this, obj.minutes, obj.seconds);
}, that);
}());
};
CountDownTimer.prototype.onTick = function(ftn) {
if (typeof ftn === 'function') {
this.tickFtns.push(ftn);
}
return this;
};
CountDownTimer.prototype.expired = function() {
return !this.running;
};
CountDownTimer.parse = function(seconds) {
return {
'minutes': (seconds / 60) | 0,
'seconds': (seconds % 60) | 0
};
};
CountDownTimer.prototype.stop = function() {
this.running = false;
};
All in, it gives me my desired result

Show message while javascript is running

I know that most probably such question has been requested several times but I have a need to show a popup or message or whatelse when a javascript function is triggered and hide it at the end.
See this simple js fiddle
That's the HTML code:
<div id='message'>Default message</div>
<input type='button' onclick='Run();' value='start'>
the div 'message' has to contain a simple text like "running" or "please wait" or ...
That's the JS function that took (delay) 3 seconds:
function Run() {
var delay = 3000; //-- 3 seconds
$( '#message' ).text('Please wait ' + delay + ' seconds...');
var start = new Date().getTime();
while (true) {
current = new Date().getTime();
if ( (start + delay) < current) {
break;
}
}
$( '#message' ).text('Done');
}
The expected behaviour is that the '#message' div contains "Please wait 3 seconds..." before to enter in the loop and "Done" string only at the end.
But that's not.
Can anyone explain me (most probably "again") why or suggest a link where to find an answer?
The JS event loop is too busy running while (true) {} to handle a DOM repaint.
Use setInterval, setTimeout, or requestAnimationFrame to trigger the next test of the time instead of a loop.
function Run() {
var delay = 3000; //-- 3 seconds
$( '#message' ).text('Please wait ' + delay + ' seconds...');
var start = new Date().getTime();
setTimeout(whenDelayIsOver, 50);
function whenDelayIsOver() {
if ( (start + delay) < current) {
$( '#message' ).text('Done');
} else {
setTimeout(whenDelayIsOver, 50);
}
}
}
… or just use setTimeout in the first place.
function Run() {
var delay = 3000; //-- 3 seconds
$( '#message' ).text('Please wait ' + delay + ' seconds...');
setTimeout(whenDelayIsOver, delay);
function whenDelayIsOver() {
$( '#message' ).text('Done');
}
}
Try this http://jsfiddle.net/aamir/23ZFY/11/
function Run() {
var secs = 3;
$('#message').text('Please wait '+ secs +' seconds...');
var timer = setInterval(function () {
if (secs == 1) {
clearTimeout(timer);
$('#message').text('Done');
return;
}
secs--;
$('#message').text('Please wait ' + secs + ' seconds...');
}, 1000);
}
The browser's display is only updated when the function completely finishes running.
You can run the second lot of code asynchronously by using setTimeout.
function Run() {
$('#message').text('Please wait 3 seconds...');
setTimeout(
function () {
var start = new Date().getTime();
while (true) {
current = new Date().getTime();
if ((start + 3000) < current) {
break;
}
}
$('#message').text('Done');
},0);
}
You have a very tight loop (while(true)...) which doesn't allow the UI to update at all. What you can do instead is this:
function Run() {
var delay = 3000; //-- 3 seconds
$('#message').text('Please wait ' + (delay/1000) + ' seconds...');
setTimeout(function () {
$('#message').text('Done');
}, delay);
}
Basically, set the "wait message" initially and use the setTimeout function to update the message again after 3 seconds.
Updated fiddle.

Categories