Reputation: 4655
on async programming, we use lots of callbacks, like this:
var running = function(){
do_sth();
$.post("/xxx", function(data){
do_sth2();
$.get("/ttt", function(data){
do_sth3();
}
}
}
and I think things should be like this:
var running = do_async(function(){
do_sth();
var data = $.post("/xxx");
do_sth2();
data = $.get("/ttt");
do_sth3();
});
How can I do that?
and there is a project on this: https://github.com/JeffreyZhao/jscex
and I think this project is not that easy to use (implementation is by parse the source code)
maybe in the future, we have a native javascript support on this?
I did some research on this, found some disscussion and library here for reference:
https://github.com/JeffreyZhao/jscex
defer coffeescript https://github.com/jashkenas/coffee-script/issues/350
merge into coffeescript: https://github.com/jashkenas/coffee-script/issues/350
tamejs library http://tamejs.org/
stratifiedjs http://onilabs.com/stratifiedjs
kaffeine http://weepy.github.com/kaffeine/
wiki page about this: http://en.wikipedia.org/wiki/Continuation-passing_style
It is not very easy to add a library to support it,
maybe in the future, javascript will add a "defer" keyword.
same question: Pattern for wrapping an Asynchronous JavaScript function to make it synchronous
Upvotes: 1
Views: 394
Reputation: 2192
I'm sure you appreciate that this async callback behaviour is by design, and not some unfortunate oversight. It's something that comes up quite a lot in the Node.js community (Node uses a similar event loop), and a number of alternatives have been developed there based on fibres, threads, etc. A couple of recent discussions are here and here, which also cover a number of these alternatives.
Edit: Another topic on async libraries on the Node forum, including discussion of
Some of the contributors wrote those / have written other flow control libraries, and I definitely found it worth checking out.
Other stuff I've read recently
I'm not sure it's a route I'd go down, though, unless you have a specific need for that sort of behaviour (e.g. workers in the browser as @MaxArt mentioned, or your code fits particularly well with a multithreaded (etc.) model) as most of these solutions are actually single threaded loops underneath. You can avoid too much nasty nesting by passing / calling named functions, e.g.
function a() {
somethingAsync(function (val) { b(val); });
}
function b(val) { ... }
Upvotes: 1
Reputation: 4748
Since JavaScript is entirely single-threaded, there is absolutely no way that you can synchronize asynchronous code.
I recommend that you practice to get the hang of things. Maybe you could try the setTimeout
function. Give it a callback and maybe make it display "Hello, World!"
on the console. And also, pass in the number 0 as the last parameter.
With that said, however, you can "prettify" asynchronous code with the help of libraries.
There is one out there that is particularly my favourite. It's called async.js. I use it all the time to keep deeply nested asynchronous calls looking more synchronous (ie, MongoDB queries).
async.waterfall([
// Call to the first asynchronous call...
function (callback) {
setTimeout(function () {
callback(null, "Hello, World!");
}, 0);
},
// That needs to make another...
function (callback, message) {
console.log(message);
setTimeout(function () {
callback(null, "It's a nice day!");
}, 0);
},
// Another...
function (callback, message) {
console.log(message);
setTimeout(function () {
callback(null, "Bye, now!");
}, 0);
},
// And another.
function (callback, message) {
console.log(message);
}
]);
// Without making the entire thing hopelessly nested deeply.
Upvotes: 0
Reputation: 664317
You might have a look into Promises. There are some implementations available, see commonjs.org. All of them allow chaining, so you can write your code as follows:
function running(){
return do_sth()
.then($.post.bind($, "/xxx"))
.then(do_sth2)
.then($.get.bind($, "/ttt"))
.then(do_sth3);
// returns a Promise to run all these tasks
// ...or: a Promise for the result of the last of the chained tasks
}
If you use jQuery, this is already built-in with the deferred functionality (not my favourite Promise implementation, though):
function running(){
do_sth();
return $.post("/xxx")
.then(do_sth2)
.then(function(){
$.get("/ttt")
.then(do_sth3);
});
}
Upvotes: 1
Reputation: 22617
Callbacks are a vital part of Javascript. Javascript is designed to make use of them. I don't think we will ever get some kind of "synchronizer". On the contrary, we're getting more and more instruments to do things asynchronously, like Worker
s.
If you feel puzzled by all these callbacks, you'd better get used to them ASAP. You'll be fine, believe me.
Anyway, AJAX request can be done synchronously, but keep in mind that this halts the execution of the script.
Upvotes: 1