迭代期间的回调范围

发布于 2024-12-10 19:32:39 字数 462 浏览 0 评论 0原文

我知道有很多关于回调、范围和闭包的问题。如果这是重复的,我提前道歉。

我有一个each 循环,它调用一个执行多个异步操作的函数,然后发出回调。当回调触发时,我(显然)失去了范围。我所做的是将循环中的项目传递给函数,然后在回调中返回它,这样我就有了我需要的范围。这是最好的方法吗?我并不是在寻找过于复杂的东西。我只是想确保我不会遇到任何“陷阱”。

function doSomething(varA, varB, self, callback) {
  // do a lot of ajax stuff
  callback(varA + varB, self);
}

$.each( $('.selected'), function(i, item) {
  doSomething('a', 'b', item, function(retVal, self) {
    // process retVal and self
  }
}

I know there are a ton of questions regarding callbacks, scope, and closures. I apologize in advance if this is a duplicate.

I have an each loop that calls a function that performs several async actions and then issues a callback. I'm losing scope (obviously) when the callback fires. What I've done is pass the item in the loop to the function and then I return it in the callback so I have the scope I need. Is that the best way to do this? I'm not looking for something overly complicated. I just want to make sure I'm not going to run into any "gotchas".

function doSomething(varA, varB, self, callback) {
  // do a lot of ajax stuff
  callback(varA + varB, self);
}

$.each( $('.selected'), function(i, item) {
  doSomething('a', 'b', item, function(retVal, self) {
    // process retVal and self
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

无戏配角 2024-12-17 19:32:39

你所得到的看起来不错,但有一件事:使用 $.each() 而不是 .each()。试试这个:

$('.selected').each(function(i, item) {
  doSomething('a', 'b', item, function(retVal, self) {
    // process retVal and self
  }
}

What you've got looks fine but for one thing: using $.each() instead of .each(). Try this:

$('.selected').each(function(i, item) {
  doSomething('a', 'b', item, function(retVal, self) {
    // process retVal and self
  }
}
客…行舟 2024-12-17 19:32:39

如果您不需要元素引用内部 doSomething,您可以用这种稍微整洁的方式创建一个闭包:

function doSomething(varA, varB, callback) {
  // do a lot of ajax stuff
  callback(varA + varB);
}

$.each( $('.selected'), function() {
  var self = this;
  doSomething('a', 'b', function(retVal) {
    // process retVal and self
  }
});

If you don't need the element reference inside doSomething, you can create a closure in this, slightly tidier way:

function doSomething(varA, varB, callback) {
  // do a lot of ajax stuff
  callback(varA + varB);
}

$.each( $('.selected'), function() {
  var self = this;
  doSomething('a', 'b', function(retVal) {
    // process retVal and self
  }
});
软甜啾 2024-12-17 19:32:39

人们在使用 ajax 和循环时遇到的主要“问题”是尝试重用稍后执行的函数内的迭代变量。例如,

for (var i in col) {
  $.ajax({
    url: '...' + i + '.html',
    success: function() {
      console.log(i);  // Why is i different???
    }
  });
}

出现此“陷阱”是因为所有 success 回调之间共享 1 个 i 实例。

在您的场景中,每个“迭代”级别都有一个 i 。所以这个陷阱不会击中你。

The main "gotcha" people run into with ajax and loops is trying to reuse the iteration variable inside the function which executes later. For example

for (var i in col) {
  $.ajax({
    url: '...' + i + '.html',
    success: function() {
      console.log(i);  // Why is i different???
    }
  });
}

This "gotcha" occurs because there is 1 instance of i shared amongst all of the success callbacks.

In your scenario though you have one i for every "iteration" level. So this gotcha won't hit you.

情定在深秋 2024-12-17 19:32:39

由于 callback 是在 .each() 函数中定义的,因此当您到达回调函数时,item 仍然在范围内。因此,如果 doSomething() 从不使用 self,则无需传递它。您可以只引用 item

function doSomething(varA, varB, callback) {  
  // do a lot of ajax stuff  
  callback(varA + varB);  
}  

$('.selected').each(function(i, item) {  
  doSomething('a', 'b', function(retVal) {  
    // process retVal and item
  });
});

现在,如果回调是在 .each() 之外定义的,您必须按照自己的方式进行操作,传递 itemdoSomething()

function doSomething(varA, varB, self, callback) {  
  // do a lot of ajax stuff  
  callback(varA + varB, self);  
}  
function doSomethingCallback(retVal, self) {  
  // process retVal and item
}

$('.selected').each(function(i, item) {  
  doSomething('a', 'b', item, doSomethingCallback);
});

Since callback is defined within the .each() function, item still is in scope by the time you get to your callback function. So, if doSomething() never uses self, you don't need to pass it. You can just reference item:

function doSomething(varA, varB, callback) {  
  // do a lot of ajax stuff  
  callback(varA + varB);  
}  

$('.selected').each(function(i, item) {  
  doSomething('a', 'b', function(retVal) {  
    // process retVal and item
  });
});

Now, if the callback were defined outside of .each(), you'd have to do it the way you have it, passing item to doSomething():

function doSomething(varA, varB, self, callback) {  
  // do a lot of ajax stuff  
  callback(varA + varB, self);  
}  
function doSomethingCallback(retVal, self) {  
  // process retVal and item
}

$('.selected').each(function(i, item) {  
  doSomething('a', 'b', item, doSomethingCallback);
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文