2011-10-20 95 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