像jQuery這樣的JavaScript工具包都是關於回調函數的,這些回調函數經常被匿名定義。示例:某個網頁顯示錶格中的消息列表。要更新此表,它可能會首先向服務器請求所有當前的消息(如ID)的列表,然後檢索內容爲尚未未知消息ID:是否有JavaScript預處理器,使回調看起來不錯?
function fnUpdateMessages() {
$.ajax({
type: 'POST',
data: { action: 'get_message_ids' },
success: function(sData) {
var aMessageIds = sData.split(/,/);
var aUnknownIds = fnWhichIdsAreNotInTable(aMessageIds);
$.ajax({
type: 'POST',
data: {
action: 'get_message_contents',
ids: aUnknownIds.join(',')
},
success: function(oData) {
for (var id in oData.messages) {
fnInsertMessage(oData.messages[id]);
}
}
);
}
);
}
你看我要去哪裏?這段代碼很難看,因爲縮進只有在後續的兩次AJAX調用之後纔在第6級。我當然可以在文件範圍內將匿名函數分割成單獨的函數,但通常會污染名稱空間(除非通過在另一個匿名函數調用中包裝這些東西來進一步混淆這些東西),並打破了這些函數之間的強大聯繫:回調應該真的不能被自己使用;它們就像原來的fnUpdateMessages
函數的第二和第三部分一樣。
我寧願要的是這樣的:
function fnUpdateMessages() {
$.ajax({
type: 'POST',
data: { action: 'get_message_ids' },
success: continue(sData)
});
var aMessageIds = sData.split(/,/);
var aUnknownIds = fnWhichIdsAreNotInTable(aMessageIds);
$.ajax({
type: 'POST',
data: {
action: 'get_message_contents',
ids: aUnknownIds.join(',')
},
success: continue(oData)
);
for (var id in oData.messages) {
fnInsertMessage(oData.messages[id]);
}
}
這個片段引入了新的假設語法continue(var1, var2, [...])
它定義了一個匿名的回調函數體是封閉的功能範圍下面的一切。這使得這些回調函數看起來像同步代碼。顯然,這將不得不進行預處理,因爲它不是標準的JS。
在我甚至考慮編寫這樣的預處理器之前,我想知道這樣的事情是否已經存在?
P.S.如果你喜歡這個想法,請偷走它。目前我還不能完成另一個項目。在評論中指向您的存儲庫的鏈接會很好,如果您想了解一些有效的代碼。
https://nicolas.perriault.net/code/2013/flatten-javascript-pyramids-with-async-js /也許這篇文章會幫助你? – 2013-02-11 08:49:50
不污染你可以使用閉包的命名空間,使回調看起來像一個對象中的私有函數,並使用該對象的一個實例來完成工作......或者你可以使用coffeescript或typescript ... – 2013-02-11 08:57:06
@limelights:看起來有趣的,但乍一看,這並不能幫助我,因爲我的行爲本質上不是可並行化的。 – 2013-02-11 09:20:05