Trying to use setInterval inside a scheduleJob and it doesn't work - discord.js

I'm having this the following code, and I'm trying to use a function inside setInterval but it just won't work... what I'm doing wrong?
const job = schedule.scheduleJob({ hour: 01, minute: 56 }, () => {
loop();
});
function loop() {
var checkminutes = 5,
checkthe_interval = checkminutes * 60 * 1000;
var i = 0;
var interval = setInterval(() => {
i++;
console.log(i); // Just trying here to see if the i value gets printed in console.. but nope..
//uploadFile();
}, checkthe_interval);
}

Had to remove the last 2 lines from the code in order to make it work.

Related

React Intl with relativeTime formatting

I'm working on a kind of dynamic timestamp for messages using Intl.
I want the timestamps to be dynamic in the way that it automatically transitions from ".. seconds ago" to "... minutes ago" to "... hours ago" to "today", after which it'll just return the date it's been posted. I know there's the <RelativeFormat> component, but I want to use the API instead.
The API has a method called intl.relativeFormat, but can't seem to figure out how to use it...
I'm a junior programmer so it's all still a bit new to me 😅😅
I appreciate your time :)
If you need more info, please let me know. I'll try to provide you with more.
Thanks!
Documentation for the RelativeFormat function can be found here - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat.
The idea is that you create an instance of relative time format function, with some pre-defined settings that you want the output to follow. For example, you can set your relative time format function to return English strings in a shortened format.
const rtf = new Intl.RelativeTimeFormat('en', { style: 'narrow' });
console.log(rtf.format(3, 'quarters'));
//expected output: "in 3 qtrs."
You also need to pass negative values in order to get labels intended for the past.
const rtf = new Intl.RelativeTimeFormat('en', { style: 'narrow' });
console.log(rtf.format(-3, 'quarters'));
//expected output: "3 qtrs. ago"
The next part leverages an answer given by #fearofawhackplanet here on StackOverflow
//The 'timestamp' function parameter is your timestamp passed in milliseconds.
function timeDifference(timestamp, locale) {
const msPerMinute = 60 * 1000;
const msPerHour = msPerMinute * 60;
const msPerDay = msPerHour * 24;
const msPerMonth = msPerDay * 30;
const msPerYear = msPerDay * 365;
const current = Date.now();
const elapsed = current - timestamp;
const rtf = new Intl.RelativeTimeFormat(locale, { numeric: "auto" });
if (elapsed < msPerMinute) {
return rtf.format(-Math.floor(elapsed/1000), 'seconds');
}
else if (elapsed < msPerHour) {
return rtf.format(-Math.floor(elapsed/msPerMinute), 'minutes');
}
else if (elapsed < msPerDay) {
return rtf.format(-Math.floor(elapsed/msPerHour), 'hours');
}
else {
return new Date(timestamp).toLocaleDateString(locale);
}
}
//
// code to test the above function
//
const fifteenSecondsAgo = new Date();
const tenMinutesAgo = new Date();
const twoHoursAgo = new Date();
fifteenSecondsAgo.setSeconds(fifteenSecondsAgo.getSeconds() - 15);
tenMinutesAgo.setMinutes(tenMinutesAgo.getMinutes() - 10);
twoHoursAgo.setHours(twoHoursAgo.getHours() - 2);
console.log(timeDifference(fifteenSecondsAgo.getTime(), 'en'));
console.log(timeDifference(fifteenSecondsAgo.getTime(), 'es'));
console.log(timeDifference(tenMinutesAgo.getTime(), 'en'));
console.log(timeDifference(tenMinutesAgo.getTime(), 'es'));
console.log(timeDifference(twoHoursAgo.getTime(), 'en'));
console.log(timeDifference(twoHoursAgo.getTime(), 'es'));
Here is a JSFiddle link to see the code running - https://jsfiddle.net/mhzya237/1/
Here is a similar idea, it also deals with future/present/past times.
function getRelativeTime(time) {
const now = new Date();
const diff = Math.abs(time - now);
const mark = (time - now) >> -1 || 1;
if (diff === 0) return new Intl.RelativeTimeFormat('en').format(0,"second");
const times = [
{ type: 'second', seconds: 1000 },
{ type: 'minute', seconds: 60 * 1000 },
{ type: 'hour', seconds: 60 * 60 * 1000 },
{ type: 'day', seconds: 24 * 60 * 60 * 1000 },
{ type: 'week', seconds: 7 * 24 * 60 * 60 * 1000 },
{ type: 'month', seconds: 30 * 24 * 60 * 60 * 1000 },
{ type: 'year', seconds: 12 * 30 * 24 * 60 * 60 * 1000 },
];
let params = [];
for (let t of times) {
const segment = Math.round(diff / t.seconds);
if (segment >= 0 && segment < 10) {
params = [(segment * mark) | 0, t.type];
break;
}
}
return new Intl.RelativeTimeFormat('en').format(...params);
}
const time = getRelativeTime(new Date(new Date().getTime() - 2 * 1000));
console.info('relative time is', time);
The function takes a time param, finds the seconds difference relative to now, uses the array map to calculate which type yields the closest match and uses it as a param for Intl.RelativeTimeFormat
You can improve getRelativeTime(time) function by either returning the params array and call Intl.RelativeTimeFormat from outside the function or also pass the locale (and options) to the function.
I'm sure there are smarter ways to get rid of the times array, perhaps by creating a wrapping closure but it will force you to "initialize" this utility function first

node.js Iterate through an array in intervall for certain times

I've been working on node.js for a short time and currently have the following problem: I would like to iterate through an array and send an http request for each element in the array. These requests should be executed every 5 seconds. In addition to this, this should be done max. 10 times.
That means every 5 seconds an http request should be sent for all elements in the array.
I have already tried a branched async for and for each loop, but I am not getting the desired result.
I know where the problem is with my code but can't find another solution.
It looks something like this:
// Set for loop
for (var i = 0; i <= 10; i++) {
setTimeout(function () {
// Iterate through every element within the array
sendItems.forEach(function (arrayItem) {
// Some code
request (.....)
// Exit condition
if (sendItems[sendItems.length - 1].status === 'Failed'|||
sendItems[sendItems.length - 1].status ==='Successful') {
if (cbFlag === false) {
interval = 0;
resolve(sendItems);
}
}
});
}interval * i);
Assuming by request you're referring to the nodejs module. Here a possible solution using something strange like a sleep :)
const request = require('request');
const _request = require('util').promisify(request);
let sendItems = [1,2,3];
let sleep = (ms) => {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log(`waiting ${ms/1000} sec..`)
resolve();
}, ms);
})
}
(async function loop() {
for (let i = 0; i < 10; i++) {
for (let id of sendItems) {
let r = await _request('https://jsonplaceholder.typicode.com/posts/'+id, { json: true })
console.log(r.body.id);
}
await sleep(5000);
} console.log("ok that's it")
})();

how to add parameter to the function in angular interval

I'm writing a function which will iterate through an array with some time interval.
eg:arr=[1,2,3,4,5,6,7]
And I want to show each element with angular interval.
$interval(step,5000,7);
function step(i){
console.log(arr[i]);
}
So it'll output the numbers inside the array in a 5 seconds' interval. How can I pass the parameter into the function? Thanks.
You could also do this way:
var arrOrig =[1,2,3,4,5,6,7],
arr = angular.copy(arrOrig), //if you want it for later
cancelPromise = $interval(step, 5000);
function step() {
console.log(arr.shift()); //take out the item from top of array
if (!arr.length) { //once array runs out
$interval.cancel(cancelPromise); //cancel interval
}
}
var arr = [1, 2, 3, 4, 5, 6, 7];
var $interval = angular.injector(['ng']).get('$interval');
var cancelPromise = $interval(step, 5000);
function step() {
console.log(arr.shift());
if (!arr.length) {
$interval.cancel(cancelPromise);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
arr.forEach(function (number, idx) {
$timeout(function () {
console.log(number);
}, 5000 * (idx + 1));
});
You want to use $timeout rather than $interval because calling $interval will set up an interval each time for each number and it won't stop until it's cleared explicitly.
var i=0;
$interval(function(){
step(i);
i++
},5000);
function step(i){
console.log(arr[i]);
}
This code will display the numbers one at a time, on repeat:
var getNextNumber = (function(){
var i = 0;
var numbers = [1,2,3,4,5,6,7];
return function(){
if(i >= numbers.length){
i = 0;
}
return numbers[i++];
};
})();
$interval(function(){
var number = getNextNumber();
console.log(number);
},5000);
See this working jsfiddle.
If you want to display them only once, use one of the $timeout solutions from one of the other answers. $interval is all about repeating some command for an indefinite amount of time, whereas $timeout is more about performing a command once in the future. See this answer for more.

clearInterval after 10sec doesnt work

I created a little Game and that should create every 1sec a enemy till there are 10 enemy (10sec)
if i do it without clearInterval it creates the whole time enemys
so i want to stop when it reach 10
var initEnemy = function ()
{
//enemy div
for(var i = 0; i < 10; i++)
var timerid = null;
function IntervalFunction()
{
var randomX = Math.floor(Math.random() * 190);
var randomY = Math.floor(Math.random() * 50);
enemy.push(new Enemy(randomX, randomY).create());
}
IntervalFunction();
setInterval(IntervalFunction,1000);
clearInterval(IntervalFunction),10000);
}
clearInterval doesn't take second argument.
And setTimeout is easier to wrap head around... A simple approach is to count how many enemies you've created so far and not run setTimeout when the limit is reached:
var initEnemies = function () {
var numEnemiesCreated = 0;
function createAnotherEnemy() {
var randomX = Math.floor(Math.random() * 190);
var randomY = Math.floor(Math.random() * 50);
enemy.push(new Enemy(randomX, randomY).create());
numEnemiesCreated += 1;
if (numEnemiesCreated < 10)
setTimeout(createAnotherEnemy, 1000);
}
createAnotherEnemy();
}
And a version with for loop, it schedules function calls 0s, 1s, 2s, ... , 9s from now:
var initEnemies = function () {
function createEnemy() {
var randomX = Math.floor(Math.random() * 190);
var randomY = Math.floor(Math.random() * 50);
enemy.push(new Enemy(randomX, randomY).create());
}
for (var i=0; i < 10; i++)
setTimeout(createEnemy, i * 1000);
}
update
Here's a version with setInterval and clearInterval. You still have to count how many enemies you've created so far, and you have to use interval id in clearInterval call. Haven't tested this, sorry!
var initEnemies = function () {
var numEnemiesCreated = 0;
var intervalId;
function createEnemy() {
var randomX = Math.floor(Math.random() * 190);
var randomY = Math.floor(Math.random() * 50);
enemy.push(new Enemy(randomX, randomY).create());
// Unschedule ourselves after 10th run
numEnemiesCreated += 1;
if (numEnemiesCreated == 10)
clearInterval(intervalId);
}
intervalId = setInterval(createEnemy, 1000);
}

Issues with using setTimeout inside of a for loop with arrays

--- UPDATE ---
Here is another attempt... The issue seems to be that the animation only happens to the third item in the for loop array I'm assuming because of the setTimeout delay. How can I have the animation fire for each item (3) with a delay?
// Breadcrumb Animation
(function(){
var header = document.getElementById("header"),
header2 = document.getElementById("header-secondary"),
banner = document.getElementById("banner");
var bcLink = [header, header2, banner];
var myTime = '';
var myItem = '';
function delay() {
setTimeout(fadeIn, myTime);
function fadeIn() {
if( myItem.style.opacity !== '1' ) {
console.log(myItem);
setInterval(function(){
myItem.style.opacity = parseFloat(myItem.style.opacity) + 0.1;
}, 100);
}
}
}
var i, len=bcLink.length;
for(var i = 0; i < len; i++) {
bcLink[i].style.opacity = 0;
myItem = bcLink[i];
myTime = myTime = parseInt(myTime + 2000)
delay();
}
})();
--- END UPDATE ---
The code below works but I was trying to optimize my code by creating a foor loop that will loop through each of the items (my attempt is commented out). I'm currently using 3 items on my page (header, header2, banner) that will load one after the other, but the second should not start until the first loads, the third should not start until the second item loads, and so on. This code will eventually be used for breadcrumbs where the amount of items will be uncertain but they will still load one after the other. Any help is greatly appreciated.
(function(){
var header = document.getElementById("header"),
header2 = document.getElementById("header-secondary"),
banner = document.getElementById("banner");
var bcLink = [header, header2, banner];
var myTime = '';
function fadeIn(name, speed) {
if( name.style.opacity !== '1' ) {
setInterval(function(){
name.style.opacity = parseFloat(name.style.opacity) + 0.1;
}, speed);
}
}
function delay(funct, time) {
setTimeout(function() {funct}, time);
}
bcLink[0].style.opacity = 0;
bcLink[1].style.opacity = 0;
bcLink[2].style.opacity = 0;
setTimeout(function(){fadeIn(bcLink[0], 100)}, 0);
setTimeout(function(){fadeIn(bcLink[1], 100)}, 1000);
setTimeout(function(){fadeIn(bcLink[2], 100)}, 2000);
// for(var i = 0; i < bcLink.length; i++) {
// bcLink[i].style.opacity = 0;
// delay(fadeIn(bcLink[i],100), i + 000);
// }
})();
use jQuery animation queue, not timeout.
http://blog.bigbinary.com/2010/02/02/understanding-jquery-effects-queue.html
Try changing:
delay(fadeIn(bcLink[i],100), i + 000);
to:
setTimeout(function(){fadeIn(bcLink[i], 100)}, i * 1000);

Resources