像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