像 jQuery 这样的 JavaScript 工具包都是关于回调函数的,而且这些回调通常是匿名定义的。示例:某些网页在表格中显示消息列表。要更新此表,它可能首先向服务器询问所有当前消息(作为 ID)的列表,然后检索未知消息 ID 的内容:
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]);
}
}
);
}
);
}
你看到我要去哪里了吗?这段代码很难看,因为在随后的 2 次 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。
在我考虑编写这样的预处理器之前,我想知道这样的东西是否已经存在?
PS如果你喜欢这个想法,请偷走它。我现在买不起另一个项目。如果您获得一些工作代码,在评论中指向您的存储库的链接会很棒。