【问题标题】:Use parameter in callbacks from function which called it在调用它的函数的回调中使用参数
【发布时间】:2023-03-28 22:45:01
【问题描述】:

如果我调用一个传递参数param的函数A,其中调用了一个异步函数B,那么异步函数B的回调C是否能够使用给函数A的参数param?如果是,如果在函数 B 开始和回调 C 被调用之间的时间内我重新调用函数 A,这会改变吗?

例子:

function A(param) {

  value1 = param;
  doc = "hello";
  //this is the async function B;
  database.insert(doc, function() {
    //this is the invoked callback C when the async function is solved. 

    console.log(value1)

    //can i log value1? yes. if yes, will this change if i re-invoke 
    //function A before the callback is invoked or two different processes will start?

  })


}


A('hello');
A('not hello');

想知道如果在上一次调用的回调函数之前第二次调用一个函数,是否会在控制台上打印正确的值:

你好; 不是你好;

永远不会 不是你好; 不是你好;

因为第二次的调用会感染第一次。

【问题讨论】:

  • var声明你的局部变量。
  • 先谢谢你。这是正确工作所需要的还是只是建议? @Pointy
  • 这只是一个非常重要的习惯,也是一个需要理解的重要概念。
  • 好的,非常感谢您的建议。但这不是我要问的! :)

标签: javascript asynchronous callback scope parameter-passing


【解决方案1】:

是的,传递给database.insert() 的内联回调将能够看到传递给函数A() 的参数。函数可以访问包含函数中的任何参数甚至局部变量。

而且,每一个都将单独保存,因此您可以根据需要多次调用A(),并且它们将各自保留单独的参数。

这个概念称为闭包,每次调用A()都会创建一个单独的闭包,只要其中的任何代码(包括异步回调)尚未完成,闭包就会保持活动状态。

您将需要在它们前面声明您的局部变量var,以使它们成为真正的局部变量并且对于A() 的每次调用都是唯一的。如果没有var,它们将成为隐式全局变量,并且A() 的一次调用将与A() 的另一次调用的全局变量混淆。如果你这样做,你是安全的:

function A(param) {

  var value1 = param;
  var doc = "hello";
  //this is the async function B;
  database.insert(doc, function() {
    //this is the invoked callback C when the async function is solved. 

    console.log(value1);
    console.log(param);
    console.log(doc);

    //can i log value1? yes. if yes, will this change if i re-invoke 
    //function A before the callback is invoked or two different processes will start?

  })


}


A('hello');
A('not hello');

【讨论】:

  • 好的,谢谢。但是如果我在第一次调用之后在第一次调用回调解决之前重新调用函数,这个值会改变吗?我的意思是,第一次调用 callbak 将打印第一个传递的参数?
【解决方案2】:

为了在回调闭包中捕获变量value1,您需要将其声明为局部变量:

var value1 = param;

【讨论】:

  • 函数参数也是闭包的一部分。无需将其分配给局部变量。
  • 没错,但他没有在回调中使用参数,而是使用value1。所以我展示了如何捕捉它。在这个示例程序中它们是可互换的,但在实际应用程序中它们可能不是(例如var value1 = param * something)。
猜你喜欢
  • 1970-01-01
  • 2019-09-10
  • 2016-08-15
  • 1970-01-01
  • 1970-01-01
  • 2014-09-19
  • 1970-01-01
  • 1970-01-01
  • 2017-12-25
相关资源
最近更新 更多