admin管理员组文章数量:1415664
JavaScript toolkits like jQuery are all about callback functions, and those callbacks are frequently defined anonymously. Example: Some webpage shows a list of messages in a table. To update this table, it might first ask the server for a list of all current messages (as IDs), then retrieve the content for the yet-unknown message IDs:
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]);
}
}
);
}
);
}
You see where I'm going? This code is ugly, since indentation is at level 6 after only 2 subsequent AJAX calls. I can of course split the anonymous functions into separate functions at the file scope, but that usually pollutes the namespace (unless one clutters stuff further by wrapping this in another anonymous function call) and it breaks the strong bond between these functions: The callbacks should really not be used by themselves; they're just like the second and third part of the original fnUpdateMessages
function.
What I'd much rather want is something like this:
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]);
}
}
This snippet introduces new hypothetical syntax continue(var1, var2, [...])
which defines an anonymous callback function whose body is everything that follows in the enclosing function scope. This makes those callback functions appear like synchronous code. That would have to be preprocessed, obviously, since it's not standard JS.
Before I even consider writing such a preprocessor, I would like to know if something like this already exists?
P.S. If you like this idea, please steal it. I can't quite afford yet another project at the moment. A link to your repository in a ment would be great, should you get to some working code.
JavaScript toolkits like jQuery are all about callback functions, and those callbacks are frequently defined anonymously. Example: Some webpage shows a list of messages in a table. To update this table, it might first ask the server for a list of all current messages (as IDs), then retrieve the content for the yet-unknown message IDs:
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]);
}
}
);
}
);
}
You see where I'm going? This code is ugly, since indentation is at level 6 after only 2 subsequent AJAX calls. I can of course split the anonymous functions into separate functions at the file scope, but that usually pollutes the namespace (unless one clutters stuff further by wrapping this in another anonymous function call) and it breaks the strong bond between these functions: The callbacks should really not be used by themselves; they're just like the second and third part of the original fnUpdateMessages
function.
What I'd much rather want is something like this:
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]);
}
}
This snippet introduces new hypothetical syntax continue(var1, var2, [...])
which defines an anonymous callback function whose body is everything that follows in the enclosing function scope. This makes those callback functions appear like synchronous code. That would have to be preprocessed, obviously, since it's not standard JS.
Before I even consider writing such a preprocessor, I would like to know if something like this already exists?
P.S. If you like this idea, please steal it. I can't quite afford yet another project at the moment. A link to your repository in a ment would be great, should you get to some working code.
Share Improve this question asked Feb 11, 2013 at 8:47 Stefan MajewskyStefan Majewsky 5,5553 gold badges32 silver badges51 bronze badges 3- nicolas.perriault/code/2013/… Maybe this article will help you out? – Henrik Andersson Commented Feb 11, 2013 at 8:49
- to not pollute the namespace you can use closure to make callbacks look like private function in an object and use an instance of that object to do the work... or maybe you could use coffeescript or typescript ... – user757095 Commented Feb 11, 2013 at 8:57
- @limelights: Looks interesting, but at first glance, this does not help me since my actions are inherently not parallelizable. – Stefan Majewsky Commented Feb 11, 2013 at 9:20
3 Answers
Reset to default 2There are only two solutions :
The first is really bad : you have to make the first ajax request synchronous but your script will block until result is available. This is really a bad solution, you should not make any ajax requests synchronous.
The second one use the jQuery.pipe function on deferred object return by $.ajax (you have to use jquery > 1.5). You can chain callbacks using pipe like this (I use internal function to make it more readable) :
[EDIT] : since jquery 1.8, you should use deferred.then instead of deferred.pipe :
function fnUpdateMessages() {
var getMessages = function() {
return $.ajax({
type: 'POST',
data: { action: 'get_message_ids' },
});
};
var getContents = function(aUnknownIds) {
return $.ajax({
type: 'POST',
data: {
action: 'get_message_contents',
ids: aUnknownIds.join(',')
},
});
};
var insertMessages = function(oData) {
for (var id in oData.messages) {
fnInsertMessage(oData.messages[id]);
}
};
getMessages()
.then(getContents)
.done(insertMessages);
}
You can use jQuery's deferreds to chain callbacks instead of including them in the options.
function fnUpdateMessages() {
$.ajax({
type: 'POST',
data: { action: 'get_message_ids' }
).done(function(sData) {
var aMessageIds = sData.split(/,/);
var aUnknownIds = fnWhichIdsAreNotInTable(aMessageIds);
$.ajax({
type: 'POST',
data: {
action: 'get_message_contents',
ids: aUnknownIds.join(',')
}
}).done(function(oData) {
for (var id in oData.messages) {
fnInsertMessage(oData.messages[id]);
}
});
});
}
It's not perfect, but it'll save you a couple levels of indentation per request.
See the documentation for $.ajax for more info.
Yes there is. It's called jwacs - JavaScript With Advanced Continuation Support. To put it simply you make use of continuations to suspend the execution of a program. You may then resume execution of the program by calling the continuation. The continuation always preserves the state of the program at the time it was created.
This is a little like trampolining in JavaScript, but trampolining depends on generators which are only supported by Mozilla products - Firefox and Rhino. If you're interested in trampolining I wrote a library to make writing asynchronous bearable. It's called Fiber and it's a little like cooperative Java threads.
On the other hand jwacs piles down to ordinary JavaScript. Hence it may be used on any platform. Not just Firefox and Rhino. If you want to understand what continuations are then I suggest you read the following StackOverflow question and answer:
The Question: What's the difference between a continuation and a callback?
The Answer: https://stackoverflow./a/14022348/783743
本文标签: asynchronousIs there a JavaScript preprocessor that makes callbacks look niceStack Overflow
版权声明:本文标题:asynchronous - Is there a JavaScript preprocessor that makes callbacks look nice? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745198141a2647238.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论