How can I perform a function only once in a period of time

Asked

Viewed 60 times

2

I wanted to know how to do a single execution, example:

In my application there is a way to schedule charges and they are scheduled per day, then on a certain day X she will be charged.


I’m currently doing it this way:

const da = Number(new Intl.DateTimeFormat('pt-br', { day: '2-digit' }).format(new Date(Date.now())));

let arr = [
  { name: "Salário", amount: 150000, day: 5 },
  { name: "Internet", amount: -11590, day: 10 },
  { name: "Teste", amount: 15000, day: 5 },
];

const indexofday = arr.reduce((acc, obj, index) => {
  if (obj.day === da) {
    acc.push(index);
  }
  return acc;
}, []);

const newarr = indexofday.map((item) => Array[item]);

//Função para adicionar essa array em outro local da aplicação. O concat e somente um exemplo!

newarr.forEach((transaction, index) => {
  datastorage.concat(transaction, index);
});

This function is what I am currently using, but when I refresh the page and the day remains the same, it runs this function again! It creates a loop in my application. Is there any way to perform this only once a day?

  • I don’t know any other way than not to use some browser storage and persist some data to be checked before running the function, because when reloading the page, all JS will run again. I’ll wait to see someone propose some creative solution.... or not.... or say I’m wrong :).

  • Remember that you do not need to obtain the indexes and then access, through indexing, the respective elements. You can do this in a single "reduction".

  • That’s interesting, good to know thank you so much! I’ll do it straight next time!

  • @Ellathet, vc means once a day (regardless of the time, each 24-hour cycle) for something that has a monthly cycle (each one x day of the month)...what comes to mind would be a cookie. When executing the function checks if there is a cookie, if it does not exist (first time) create one. You can use timestamp as value and 30 days as expiration, if it exists compares its value (timestamp)...if it has passed 24 hours runs the function again and saves a new one cookie with the current timestap, if not use return to leave the function without doing anything. Every 30 days the cookie is excluded and a new created.

  • @Lauromoraes, I understood, I didn’t understand very well without some example, I never used this function of cookies. I’ll do some research, if you can help me by sending me an example of timestamp, thanks!

  • @Ellathet, published an example as a response. try to suit your needs

Show 1 more comment

1 answer

1


Following the logic you intend to apply:

  • the script must be executed once every 24hs period
  • its function checks if the current day is equal to the billing day (monthly)
  • if it is equal executes

I believe you should move your code to a function that checks a time indicator and makes the following comparison:

  • 1: get if indicator exists, if it does not exist. Create and call the function
  • 2: if the indicator exists, check if it is greater than the current period (24hs)
  • 3: if the period is longer, sets a new indicator and performs the function
  • 4: if the period is shorter, does not perform the function and does not adjust the current indicator

I can’t say it’s the best indication but, use a Timestamp as indicator would allow to make this check in the "front-end".

There are "n" modes of storing this indicator in "front-end", here I am using document.cookie and taking the liberty of modifying the day from its first collection object to the present day so you can see that the cookie is created and the function is called only once ... There will only be called again after 24hs.

NOTE: concealed the exit of console of the snippet below because it runs on a <iframe> and cannot save cookies for security reasons.

// defina um nome mais apropriado
const SuaFunção = function() {
    // millisegundos de 24Hs
    const DayInMilliseconds = (24 * 60 * 60 * 1000)
    // cookie search
    const search = name => {
        return document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + name.replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1") || false
    }
    // função que retorna a data de expiração do cookie (formato GMT)
    const makeTime = t => {
        if ( typeof t === 'number' ) {
            let d = new Date()
            d.setMilliseconds(d.getMilliseconds() + t * DayInMilliseconds)
            return d.toString()
        }
    }
    //
    const paymentFn = () => {
        const da = Number(new Intl.DateTimeFormat('pt-br', { day: '2-digit' }).format(new Date(Date.now())));

        let arr = [
          { name: "Salário", amount: 150000, day: da },
          { name: "Internet", amount: -11590, day: 10 },
          { name: "Teste", amount: 15000, day: 5 },
        ];

        const indexofday = arr.reduce((acc, obj, index) => {
          if (obj.day === da) {
            acc.push(index);
          }
          return acc;
        }, []);

        const newarr = indexofday.map((item) => Array[item]);

        //Função para adicionar essa array em outro local da aplicação. O concat e somente um exemplo!

        newarr.forEach((transaction, index) => {
          //datastorage.concat(transaction, index);
          console.log(transaction, index)
        });
    }

    // procura seu cookie (exemplo: "payment")
    const PaymentCookie = search('payment'),
        // pega o Timestamp atual
        TSNow = Date.now()
    if ( PaymentCookie ) {
        /*
           verifica se o Timestamp do cookie + um periodo de 24Hs (em millisegundos) é maior que o atual Timestamp
           o que significa que ainda não se passaram 24Hs
         */ 
        if ( Number(PaymentCookie) + DayInMilliseconds > TSNow ) {
            // o Timestamp do cookie ainda não passou de 24Hs
            console.log('Ainda não passaram mais de 24Hs')
            // retorna sem fazer nada, não invoca sua função de cobrança
            return
        }
        // o Timestamp do cookie já passou de 24Hs
        console.log('Já passaram mais de 24Hs')
        // caso a instrução acima não execute (por já ter passado de 24Hs) cria um novo cookie
        document.cookie = `payment=${TSNow}; expires=${makeTime(30)}`
        // executa sua função
        paymentFn()
    } else {
        // primeira execução
        console.log('Não há cookie, vamos criar um')
        // cria novo cookie com o atual Timestamp e executa sua função (expira em 30 dias)
        document.cookie = `payment=${TSNow}; expires=${makeTime(30)}`
        // chama sua função
        paymentFn()
    }
}

// chama a função em qualquer parte do script principal
SuaFunção()


Sources:

https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Greater_than


Additional reading:

https://hkotsubo.github.io/blog/2019-05-02/o-que-e-timestamp

Convert date from DD/MM/YYYY to YYYY-MM-DD in Javascript

  • I managed to use this shape here, but it is in the whole function, so when I add an item in this arr it does not update because the command is still in timestamps, as I would do this in a way that it checks per item in the array, it would have to create a property on the object within the array has this expire?

  • If I understand, you can move your Array out of function ... In function just call it was that?

  • Actually that Array is a localStorage browser, the question is that since the function runs only once, if I add a few more things in this localStorage it does not perform because it has the time period, it would have to have a time period for each item of the array?

  • @Ellathet, in vdd not. If this Array this in localStorage vc can manipulate it anywhere in your script not necessarily within the function. Within the function vc only checks and calls this Array and will always have in the function the updated data even if you make changes outside it. Ex: let arr = localStorage['nome_do_objeto'] ? localStorage['nome_do_objeto'] : []; ... so if you feel changes out, you will have the current data when you invoke the function.

  • then the problem I’m having is that in this array/localStorage more automatic transactions are added, then example: It performs this function, if I want to add something else in the array it does not update because the cookie hangs the whole function!

  • I believe that the cookie is doing what he was proposed to do: run the function only every 24 hours...as said in the above comment you can update your Array out of function, in the function seeks its Array in localStorage to get the billing updates. If not, I believe that you should try to edit your question by supplementing it with what is missing and clarifying a little more. Maybe then I can better understand and change my answer or someone will come up with an answer closer than searches.

  • I took a look at his git if I can send you a Pull request

  • @Lauromoreas, I would thank you! If you have something explaining I really wanted to learn, but I accept this help yes!

Show 3 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.