简体   繁体   中英

What stands behind asynchronicity in Javascript - event-driven system

please help me understand this.

You have a function that calls a few methods:

function() {
   methodA(function(){...});
   methodB();
   methodC();
}

From languages that don't have callbacks or anonymous functions I got used to the fact, that the execution doesn't go on until a method returns.

So that if I called methodA with the callback, the execution would have to wait until the method returns which wouldn't be asynchronous, right ?

So that, for instance, I can store the callback to some object and have the methodA return. Then methodB and methodC are executed. And when user clicks a button, some handler executes the callback ?

I've come to conclusion that there is nothing asynchronous about javascript in comparison with java or python (not regarding multithreading).... because in java the callback wouldn't be closure/anonymous method, but an object with "execute" method and it would be exactly the same, just a little bit more complicated ... Of course there is this JS event system specific for DOM

Callbacks in JavaScript do not implicitly add asynchronous behavior. When a callback function is invoked, it runs right then , just as a normal function. (Actually, a callback function is just a normal function...)

Because of this, it is impossible to determine when the execution of the callback in the example will run in relationship to the other methods (except that it can't run before methodA is invoked) -- it could be called from methodA or methodB or from a click later, or not at all. (However, unless there is an exception -- or one of the functions invokes one of the other functions -- then methodA will run before methodB which will in turn run before methodC ; if methodA threw an exception then neither methodB nor methodC would be invoked).

What does add asynchronous behavior is an asynchronous event source , such as a timer event or UI action such as a button click.

However, it is important to keep in mind that Javascript does not have or support threading. The Javascript must "stop" (execution must return from the callback function invoked from an asynchronous event source) before a new asynchronous event can be triggered. (Asynchronous events are queued [as appropriate] so a timer event won't be "lost" if another callback takes too long to execute.)

This is why while (true) {} will make a browser page freeze and prevent button event handlers from being processed.

Happy coding.


Example cases ( jsfiddle demo ):

function invokeNow(callback) {
   // nothing asynchronous going on here.
   // the callback is invoked right now and the result is returned.
   return callback()
}
alert(invokeNow(function () { return "Hello world!" }))

function doLater(callback) {
    // setup an asynchronous event
    setTimeout(callback, 1000)
    return "It isn't 'later' yet!"
}

alert(doLater(function () {
    alert("Later!")
    // note that this is running in the callback from the previous
    // timer event. if this code was below the outer alert then
    // it wouldn't have allowed the first timer callback to have occurred
    // until the blocking while was complete
    alert(doLater(function () { alert("I still ran!") }))
    var end = (+new Date) + 4000
    while ((+new Date) < end) { /* wait */ }
    alert("I am done waiting")
}))

Warning: There seems to be an issue with Firefox 4 (4.0.1) and the code above. While it works as demonstrated, the expected order differs from the actual order if the timeout is below about 800ms. I have posted SO: Asynchronous timer event running synchronously (“buggy”) in Firefox 4? so hopefully there will be some resolution. The behavior works as expected in Firefox 3, IE 9, and Chrome 11.

function main() {
   methodA(function callback(){...});
   methodB();
   methodC();
}

Assuming that callback is not immediately executed.

Execution order:

  • methodA
  • methodB
  • methodC
  • ... other things until the stack is empty
  • callback

Javascript is sequential except if you use setInterval , setTimeout , or make a request to a server with a callback or using onload . Not sure there are other cases.

If you have something like:

function methodA(fn){
  ...
  fn();
}

Then the callback will be called when you call methodA(function(){...})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM