user972418
user972418

Reputation: 827

Javascript: calling function only once

Here is a piece of code:

if (lastPosition == 0) {
  callsomemethod(param);
}

I have this weird situation, wherein I have to call the function callsomemethod(param); even when the if condition is true more than once. In other words, I want to make sure that the function callsomemethod gets called only once even the if statement is true more than once. There are more things happening inside the if statement, I have just taken them out for simplicity.

EDIT:: Thanks for all the responses. Unfortunately, none of the approach is working because the if statement is inside an function and that function is called more than once so everything gets initialized again. Also that function is inside an IIFE. Apologies for not making everything clear in the first shot.

Thanks in advance

Upvotes: 1

Views: 18755

Answers (6)

Deepak Singh
Deepak Singh

Reputation: 1145

in my react native, there is a function(function name is submitData()) that continuously runs every 10 seconds. I want another function(function name is callOnlyOnce()) inside my submitData() function but here I callOnlyOnce() function run only the first time.

so I used

let myResult;

  var callOnlyOnce =(function(){
    return function(){
      if (!opop){
        // console.log(`checking value`,executed)
        opop = true
        // console.log(`checking new log value`,executed)
        const x =1
        const y =3
        myResult = x+y
        console.log(`Log inside the function`,myResult,opop)
      }
    }
  })()  
  callOnlyOnce()

and opop defines above the main function

import * as React from 'react';
let opop = false

Upvotes: 0

Dominik G
Dominik G

Reputation: 614

Here is another way yet similar to previous responses. You can use Function prototype to add call-once behaviour. In below code only first invocation will print results.

function callSomeMethod(param){
  console.log('called...'+param);
};

Function.prototype.onlyOnce = function(param){
  if(!this.wasCalled && this == callSomeMethod){
    this(param);
    this.wasCalled = true;
  }
};


function outerMethod(){
  callSomeMethod.onlyOnce('foo');
  callSomeMethod.onlyOnce('bar');
}

outerMethod();

Upvotes: 0

ssube
ssube

Reputation: 48267

The idiomatic way to do this is with a lock variable, optionally hidden via closure. The simplest example would be:

var done = false;
function callOnce(lastPosition) {
  if (lastPosition == 0 && !done) {
    done = true;
    callSomeMethod(lastPosition);
  }
}

To produce functions that can only be called once, you can use closure and wrap that:

function wrapOnce(fn) {
  var done = false;
  return function (...args) {
    if (!done) {
      done = true;
      return fn.apply(this, args);
    }
  }
}

(the ...args syntax may not work in older browsers and should be replaced with code to verify arguments and pass it down, which I have ommitted for brevity)

This is the basis of helpers like lodash's once.

Since JS only allows a single thread to access variables, this is inherently thread-safe (such as it applies) and will not break if multiple callbacks attempt to use the once-ified method.

Upvotes: 8

Ouroborus
Ouroborus

Reputation: 16875

Add a flag to track if the function was called previously or not:

var wasCalled = false;

// ...

if (lastPosition == 0) {
  if(!wasCalled) {
    wasCalled = true;
    callsomemethod(param);
  }
}

More advanced, take advantage of closures to wrap up the whole thing:

var callsomemethod = (function(){
  var wasCalled = false;
  return function(param){
    if(wasCalled){
      return;
    }
    else {
      wasCalled = true;
    }
    // callsomemethod()'s inner code goes here
  };
})();

Upvotes: 1

Chris Zimmerman
Chris Zimmerman

Reputation: 331

You could have a boolean called called that you set to true when you call the method the first time:

var called = false;
if (lastPosition == 0) {
  if(!called){
    callsomemethod(param);
    called = true;
  }
}

Upvotes: 0

Andrei Filimon
Andrei Filimon

Reputation: 1188

Declare a global variable var ran=false, set it to true inside callsomethingmethod, and extend your if like:

if(lastposition==0 && ran==false)
{
callsomemethod(param);
}

Upvotes: 0

Related Questions