简体   繁体   English

Javascript:仅调用一次函数

[英]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); 我有这种奇怪的情况,我必须调用函数callsomemethod(param); even when the if condition is true more than once. 即使if条件为真不止一次。 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. 换句话说,我想确保即使if语句为true,函数callsomemethod只会被调用一次。 There are more things happening inside the if statement, I have just taken them out for simplicity. 在if语句中还有更多的事情发生,为了简单起见,我将它们删除了。

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. 不幸的是,这种方法都不起作用,因为if语句位于函数内部,并且该函数被多次调用,因此所有内容均再次初始化。 Also that function is inside an IIFE. 该功能也位于IIFE内部。 Apologies for not making everything clear in the first shot. 抱歉在第一枪中没有将所有内容弄清楚。

Thanks in advance 提前致谢

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) ...args语法可能在较旧的浏览器中不起作用,应替换为代码以验证arguments并将其传递给我,为了简洁起见,我省略了该语法)

This is the basis of helpers like lodash's once . 这是lodash曾经的助手的基础。

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. 由于JS只允许单个线程访问变量,因此它本质上是线程安全的(如适用),并且如果多个回调尝试使用once标准化的方法也不会中断。

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
  };
})();

Declare a global variable var ran=false, set it to true inside callsomethingmethod, and extend your if like: 声明一个全局变量var ran = false,在callsomething方法中将其设置为true,并扩展if:

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

You could have a boolean called called that you set to true when you call the method the first time: 你可以有一个布尔叫called你设置为true,当你调用该方法的第一次:

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

Here is another way yet similar to previous responses. 这是另一种类似于先前响应的方式。 You can use Function prototype to add call-once behaviour. 您可以使用Function原型添加一次调用行为。 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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM