在 javascript 中的循环内使用回调时,有没有办法保存在循环中更新的变量以供回调使用?

IT技术 javascript callback
2021-02-04 00:26:19

假设我有以下内容:

for(var i = 0; i < length; i++){
  var variable = variables[i];
  otherVariable.doSomething(variable, function(err){ //callback for when doSomething ends
    do something else with variable;
  }

到回调被调用时,variable将不可避免地成为所有回调的最后一个变量,而不是每个回调的不同变量,正如我所希望的。我意识到我可以传递variabledoSomething()然后将其作为回调的一部分传回,但它doSomething()是外部库的一部分,我宁愿不要为此弄乱源代码。

你们中那些比我更了解 JavaScript 的人是否知道是否有其他方法可以做我想做的事情?

最好的,谢谢,
萨米

2个回答

处理这种情况的一种常见方法(如果很丑陋)是使用另一个函数,该函数会立即被调用以创建一个作用域来保存变量。

for(var i = 0; i < length; i++) {
  var variable = variables[i];
  otherVariable.doSomething(function(v) { return function(err) { /* something with v */ }; }(variable));
}

请注意,在立即调用的函数内部,正在创建和返回的回调将参数引用到函数v而不是外部variable为了更好地阅读,我建议将回调的构造函数提取为命名函数。

function callbackFor(v) {
  return function(err) { /* something with v */ };
}
for(var i = 0; i < length; i++) {
  var variable = variables[i];
  otherVariable.doSomething(callbackFor(variable));
}
嗯,所以我想我有点困惑。工作的方法doSomething()是它传递变量,然后最终doSomething()将调用指定的回调函数,其中第一个参数是由doSomething(). 如果我function(variable)在回调周围放置一个包装器来创建一个新的作用域,那会不会function(variable)变成回调,而参数variable实际上是错误消息?
2021-03-20 00:26:19
不幸的是,这对我来说没有帮助,因为 doSomething() 是我不想编辑的库中的函数。随着这个库的更新,我将不得不继续重新编辑源代码,这是我不想处理的事情。假设我不能改变函数 doSomething(),有什么我可以做的吗?
2021-04-01 00:26:19
这不需要对doSomething(). 我假设这doSomething只是一个回调,并且包含variable参数是您可能建议更改的内容。如果签名为doSomethingdoSomething(val, callback)则只需将我的示例修改为otherVariable.doSomething(variable, callbackFor(variable)). 重要的是通过调用函数创建了一个新的作用域,以保持variable回调函数的值
2021-04-11 00:26:19

好吧,我似乎想通了。我需要做的是在function(var)周围放置一个包装器otherVariable.doSomething(),因此更新后的代码如下所示:

for(var i = 0; i < length; i++){
  var variable = variables[i];
  (function(var){ //start wrapper code
    otherVariable.doSomething(var, function(err){ //callback for when doSomething ends
      do something else with var; //please note that i'm dealing with var here, not variable
    }
  })(variable);//passing in variable to var here
}

希望这可以帮助其他任何人在未来陷入这样的困境!

@ aparker42,我仍然希望在对您的问题的评论中听到您对我的问题的回答,因为这仍然让我感到困惑。

编辑:当然,因为这是 javascript,你不会想var用作变量名。

var在 JavaScript 中命名标识符可能不是一个好主意
2021-03-16 00:26:19
是的,这与我的回答本质上是一样的。不同之处在于您使用立即调用的函数来创建一个作用域,您可以在该作用域中调用doSomething. 我的回答只是在该范围内创建了回调,然后将其返回。最终他们都达到了同样的目的。
2021-03-24 00:26:19
为了支持和澄清,是的,这与 aparker42 提出的答案相同,只是格式不同。在这种情况下,doSomething 不会调用回调,它会立即返回一个值。
2021-03-24 00:26:19
很棒的工作,保存了我的代码。
2021-04-05 00:26:19