Javascript:只调用一次函数

Javascript:只调用一次函数,javascript,Javascript,下面是一段代码: if (lastPosition == 0) { callsomemethod(param); } 我有一个奇怪的情况,我必须调用函数callsomethod(param);即使if条件多次为真。换句话说,我想确保函数callsomethod只被调用一次,即使if语句多次为true。if语句中发生了更多的事情,为了简单起见,我刚刚将它们去掉 编辑::感谢所有的回复。不幸的是,这两种方法都不起作用,因为if语句位于函数内部,并且该函数被多次调用,因此所有内容都会再次初始化。

下面是一段代码:

if (lastPosition == 0) {
  callsomemethod(param);
}
我有一个奇怪的情况,我必须调用函数callsomethod(param);即使if条件多次为真。换句话说,我想确保函数callsomethod只被调用一次,即使if语句多次为true。if语句中发生了更多的事情,为了简单起见,我刚刚将它们去掉

编辑::感谢所有的回复。不幸的是,这两种方法都不起作用,因为if语句位于函数内部,并且该函数被多次调用,因此所有内容都会再次初始化。这个函数也存在于生命中。为没有在第一枪中把一切都说清楚而道歉


提前感谢

实现这一点的惯用方法是使用锁变量,可以选择通过闭包隐藏。最简单的例子是:

var done = false;
function callOnce(lastPosition) {
  if (lastPosition == 0 && !done) {
    done = true;
    callSomeMethod(lastPosition);
  }
}
要生成只能调用一次的函数,可以使用闭包和换行符:

function wrapOnce(fn) {
  var done = false;
  return function (...args) {
    if (!done) {
      done = true;
      return fn.apply(this, args);
    }
  }
}
(在较旧的浏览器中,
…args
语法可能不起作用,应替换为验证
参数并向下传递的代码,为了简洁起见,我建议使用该代码)

这是帮助者喜欢的基础


由于JS只允许一个线程访问变量,因此它本质上是线程安全的(如适用的),并且如果多个回调尝试使用
一次
-ified方法,它不会中断。

实现这一点的惯用方法是使用锁变量,可以选择通过闭包隐藏。最简单的例子是:

var done = false;
function callOnce(lastPosition) {
  if (lastPosition == 0 && !done) {
    done = true;
    callSomeMethod(lastPosition);
  }
}
要生成只能调用一次的函数,可以使用闭包和换行符:

function wrapOnce(fn) {
  var done = false;
  return function (...args) {
    if (!done) {
      done = true;
      return fn.apply(this, args);
    }
  }
}
(在较旧的浏览器中,
…args
语法可能不起作用,应替换为验证
参数并向下传递的代码,为了简洁起见,我建议使用该代码)

这是帮助者喜欢的基础


由于JS只允许一个线程访问变量,因此它本质上是线程安全的(如适用),并且如果多个回调尝试使用
一次
-ified方法,则不会中断。添加一个标记以跟踪函数之前是否被调用:

var wasCalled = false;

// ...

if (lastPosition == 0) {
  if(!wasCalled) {
    wasCalled = true;
    callsomemethod(param);
  }
}
更高级的是,利用闭包来结束整个过程:

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

添加一个标记以跟踪函数是否以前调用过:

var wasCalled = false;

// ...

if (lastPosition == 0) {
  if(!wasCalled) {
    wasCalled = true;
    callsomemethod(param);
  }
}
更高级的是,利用闭包来结束整个过程:

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

声明一个全局变量var ran=false,在callsomethingmethod内将其设置为true,并扩展您的if-like:

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

声明一个全局变量var ran=false,在callsomethingmethod内将其设置为true,并扩展您的if-like:

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

第一次调用该方法时,可以将名为
的布尔值设置为true:

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

第一次调用该方法时,可以将名为
的布尔值设置为true:

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

这是另一种方式,但与之前的回答类似。您可以使用函数原型添加一次调用行为。在下面的代码中,只有第一次调用才会打印结果

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

这是另一种方式,但与之前的回答类似。您可以使用函数原型添加一次调用行为。在下面的代码中,只有第一次调用才会打印结果

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

替换它
callsomethod=function(){}
我想说,最简单的方法就是添加另一个字段
methodcalled
,以检入if语句,在调用该方法时将其翻转为true。你不这么做有什么原因吗?换掉它
callsomethod=function(){}
我想说,最简单的方法就是添加另一个字段
methodcalled
,以检入if语句,在调用该方法时将其翻转为true。您不这样做有什么原因吗?或者对于多个调用站点,将逻辑放在callsomemethod()中,或者对于多个调用站点,将逻辑放在callsomemethod()中。扩展运算符,
,是ES6中非常旧的浏览器上不可用的东西之一。@Ourobrus我知道(并将在答案中添加注释)。在我看来,这只是使示例更易于阅读。扩展运算符,
,是ES6中的一种,在非常旧的浏览器上是不可用的。@Ourobrus我知道(并将在答案中添加注释)。在我看来,这只是让这个例子更容易阅读。