2011-10-20 59 views
1

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

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

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 
    } 
} 

回答

2

你有什么看起来不错,但一两件事:用$.each()代替.each()。试试这个:

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

也就是说比我有更好的语法。 – Jay

1

如果你不需要内部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 
    } 
}); 
+0

我实际上试过用这种方法使用闭包。如果自我在循环中,那么它就失去了范围。如果我将它移到循环之外,那么在回调发生之前,循环会多次执行(并且更改self的值)。问题在于循环一直在持续,回调随时触发。 – Jay

0

主要的“疑难杂症”的人跑与ajax和循环试图重用函数内部的迭代变量,稍后执行。例如

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

这种“疑难杂症”发生时,因为有在所有的success回调共享的i 1个实例。

在您的情况下,尽管每个“迭代”级别都有一个i。所以这个陷阱不会打你。

0

由于在.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); 
}); 
+0

这对我来说很有意义,这就是我所相信的,但它并没有以这种方式工作。当回调被触发时,我和物品都未定义。 – Jay

+0

@Jay - 在这种情况下,您的代码会有更多的事情发生。看到这个工作演示:http://jsfiddle.net/gilly3/czWYK/。 – gilly3

+0

我明白了。我的每个块都包含在一个对象内部的函数中,并且发出回调的函数当前只是一个常规函数。这可能是问题吗?由于XSS和其他许多噪音,我的实际代码不会有意义,但是如果我能够抽出一个有意义的例子,我会的。我的工作主要是通过状态,但看起来很丑陋。 – Jay