Why do callbacks functions allow us to do things asynchronously in Javascript?

試著忘記壹切 提交于 2019-12-05 07:44:25

问题


I've read that callbacks make JavaScript asynchronously. But I'm not sure if I understood the explanation. This is what I get

Callback functions allow us to do things asynchronously, since they ensure that the lines prior to the callback are completely finished before loading the next line.

Is that true? Thanks


回答1:


First off, it isn't the callback that enables anything. A given operation in node.js or even browser-based javascript either is or isn't asynchronous. It really has nothing to do with the callback, though a callback is typically used to communicate results of an asynchronous operation.

For example, Javascript's array.forEach() uses a callback, but it is not asynchronous. So, async operations are async because their underlying implementation is non-blocking. You start the operation by making a function call, the operation proceeds in the background and the rest of your code continues to run. Meanwhile, when the asynchronous operation completes, it usually then needs to tell your code that it is done and perhaps communicate some results. A callback function is the chosen mechanism for communicating the completion of the async operation.

I've read that callbacks make JavaScript asynchronously.

No, that is not really true. Callbacks can be used with synchronous operations too. Just because one uses a callback does not make anything asynchronous. The underlying native code implementation of an operation must be asynchronous (such as an Ajax call or other networking operation). Callbacks are used to communicate the results of asynchronous operations. They are also have many other non-asynchronous uses too. So, a callback is just one tool used in an asynchronous operation and a callback is a tool with many other uses too. You cannot say callback === asynchronous.

Callback functions allow us to do things asynchronously, since they ensure that the lines prior to the callback are completely finished before loading the next line.

It is hard to tell exactly what you mean by this, but it sounds wrong to me. When using asynchronous operations, code is typically not executed in the order laid out in the file. For example, if you did this:

console.log("async start");
callSomeAsyncOperation(function(result) {
    console.log("async done");
});
console.log("I'm here now");

You would see this in the log:

async start
I'm here now
async done

Callbacks and Event Queues Explained

It may also be useful to understand how an asynchronous operation works. Javascript works off an event queue. A given sequence of Javascript code runs to its completion. When that completes, the engine looks in the event queue to see if there are any more events to process. If so, the first event in the queue is pulled out and a callback that was registered for that event is called. This starts a new sequence of Javascript code running. That code continues to run until it finishes. When it finishes, the engine checks for another event. If there is one, it is then processed by calling a callback associated with that event. When there are no more events to process, the engine goes to sleep waiting for the next event. When an event occurs (outside the main Javascript thead), it is then added to the queue and that process of adding it to the queue causes the JS engine to wake up and service that event.

When writing your Javascript, you will often register and event handler for an event. The way this works in Javascript is that you say what event you're interested in (which may also include specifying some other information like what object you're looking for events on) and then you pass it is a function reference. You are, in essence, telling the Javascript engine that you want it to call your function reference when this event occurs. This type of function reference is referred to as a "callback". It's just a normal function, but the context in which it is being used is called a "callback" because some other code will "call you back" at some time in the future by executing your function. You can then place appropriate code in that function reference (inside that callback function) that can respond to that event. Depending upon the type of event, you may only get called once or it may call you every time that event occurs.

You can read more about how this event queue and callbacks work in these references:

Run Arbitrary Code While Waiting For Callback in Node?

blocking code in non-blocking http server

Hidden threads in Javascript/Node that never execute user code: is it possible, and if so could it lead to an arcane possibility for a race condition?

How does JavaScript handle AJAX responses in the background? (written about the browser, but concept is the same)




回答2:


First of all, let's understand what callback is (by definition):

In computer programming, a callback is a piece of executable code that is passed as an argument to other code, which is expected to call back (execute) the argument at some convenient time. The invocation may be immediate as in a synchronous callback, or it might happen at later time as in an asynchronous callback. In all cases, the intention is to specify a function or subroutine as an entity that is, depending on the language, more or less similar to a variable.


Now, talking about Javascript, not always a callback is asynchronous. For example:

function syncOperation(callback) {
  callback();
}

syncOperation(function() {
  console.log('a');
  console.log('b');
});

console.log('c');

That callback is synchronous, since it doesn't make any asynchronous operation. If you open your console and run the code above, you'll see that it will log a, then b, then c.


Now, let's see an asynchronous example:

function asyncOperation(callback) {
  setTimeout(callback, 0);
}

asyncOperation(function() {
  console.log('a');
  console.log('b');
});

console.log('c');

You'll see firstly c, then a, and b. That's because the setTimeout function runs asynchronously.

Some built-in Javascript functions are asynchronous, and they will run, and at some time, they will call the function you passed as parameter back. That's why if you do:

var a = 'text';
setTimeout(function() { a = 'new text'; }, 0);
console.log(a);

You'll see in your console text, because it will run before the variable has been changed.



来源:https://stackoverflow.com/questions/33004731/why-do-callbacks-functions-allow-us-to-do-things-asynchronously-in-javascript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!