JavaScript中的异步行为和回调 [英] Asynchronous behavior and callbacks in javascript

查看:92
本文介绍了JavaScript中的异步行为和回调的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在各个网站上跳来跳去,但不明白回调如何使javascript异步。据我了解,回调是在另一个函数内部调用的任何函数。这只是另一个函数调用。 javascript如何得知要异步执行的函数以及如何在后台进行处理?

I was hopping around various websites but couldn't understand how callbacks make javascript asynchronous. To my understanding callbacks are any functions that are called inside one another function. It is just another function call. How does javascript know which functions to execute asynchronously and how it handles under the hood?

示例代码1

function A(x){
//...code for func A;
}

function B(y){
//...code for func B;
A(2);  // 2 for example
}

示例代码2:

function A(x){
//...code for func A;
}

function B(y,A){
//...code for func B;
A(2);  // 2 for example
}

请解释一下javascript如何区分这两段代码?

Kindly explain how javascript differentiates between these two pieces codes?

推荐答案


我在各个网站上跳来跳去,但不明白回调如何使javascript异步。 / p>

I was hopping around various websites but couldn't understand how callbacks make javascript asynchronous.

他们没有。您自己发布的代码不是异步的。回调本身并不是一个异步模式(例如,请参见 Array.prototype.forEach ),但是它们被用作处理异步行为的一种方式。

They do not. The code you posted, by itself, isn't asynchronous. Callbacks are not an asynchronous pattern on their own (as an example look at Array.prototype.forEach) but they are used as one way to handle asynchronous behavior.


To我的理解回调是在另一个函数内部调用的任何函数。这只是另一个函数调用。

To my understanding callbacks are any functions that are called inside one another function. It is just another function call.

基本上,除了它们也作为参数传递。当我们说用javascript进行回调时,通常是指从一个函数传递到另一个函数,并回调初始函数,也就是名称的函数。但是,一般而言,回调只是一段可执行代码,它作为参数传递给其他代码。

Basically, except that they are also passed as arguments. When we say a callback in javascript, we usually mean functions that are passed down from one function to another and that call back the initial function, hence the name. In general however, a callback is just a piece of executable code, that is passed as an argument to other code.

您在此处提供的两个示例之间的主要区别是它们如何获得彼此的访问权限,而不是异步还是同步。

The main difference between the two samples you provided here is how they obtain access to each other, not whether they are asynchronous or synchronous.

两个示例都包含同步代码,但其中只有一个包含回调:

Both samples contain synchronous code but only one of them contains a callback:


  • 示例1:函数B通过其全局范围获得对A的访问。 不回调

  • 示例2:函数B通过其参数访问A:回调

  • Sample 1: function B obtains access to A via its global scope. not callback
  • Sample 2: function B obtains access to A via its arguments: callback

对于示例1,无论您如何称呼 B(y),因为它总是 在内部调用 A ,它不回调任何东西,只调用另一个函数。

For sample 1, no matter how you call B(y), since it always invokes A internally, it doesn't callback anything, it just calls another function.

对于示例2,您可以调用 B(y,A) B(y,C)和另外一个函数C(){} ,它将调用您传递给它的任何函数。

For sample 2, you can call B(y, A) or B(y, C) with another function C(){} and it will call back whichever function you passed into it.

如果重命名如下函数,可能会减少混乱:

Perhaps it would be less confusing if you renamed the functions like this:

function A(x){
  //...code for func A;
}

function B(y){
  //...code for func B;
  A(2);  // calls above A()
}



示例代码2:



Sample Code 2:

function A(x){
  //...code for func A;
}

function B(y, callback){
  //...code for func B;
  callback(2);  // calls whichever callback you pass in
}






演示示例


Demonstration examples

// EXAMPLE 1

function A1() {
  console.log('A1 is called');
}

function B1() {
  console.log('B1 is called');
  A1(2); // calls above A()
}

B1();
// Output:
// B1 is called
// A1 is called

B1('whatever');
// Output:
// B1 is called
// A1 is called

// EXAMPLE 2

function A2() {
  console.log('A2 is called');
}

function B2(callback) {
  console.log('B2 is called');
  callback(); // calls whichever callback you pass in
}

// We can callback to any function (but not no function)

B2(A1);
// Output:
// B2 is called
// A1 is called

B2(A2);
// Output:
// B2 is called
// A2 is called

B2();
// Output:
// B2 is called
// Uncaught TypeError: callback is not a function (because we didn't pass anything as the callback)

setTimeout演示一些异步行为。 函数。我将使用示例代码1,因为它不包含任何回调代码,还显示了回调如何与异步行为联系在一起。

Now let's demonstrate some asynchronous behavior with a common tool, the setTimeout function. I will use sample code 1 because it doesn't contain any callback code, to also show how callbacks tie into async behavior.

function A(x){
  //...code for func A;
}

function B(y){
  //...code for func B;
  setTimeout(A, 3000); // call A after 3 seconds
}

B();

在上面的代码中,函数 A 是作为回调传递给函数 setTimeout 。这意味着 setTimeout 的定义在概念上看起来像这样:

In the code above, function A is passed as a callback to function setTimeout. That means that setTimeout definition would conceptually look something like:

function setTimeout(callback, duration) {
 // call callback after duration milliseconds
}

执行上述代码时发生的事情是,词法分析器首先将功能提升到代码的顶部。然后发生 B()的调用,后接所有同步代码后记,因为JS是单线程的。
这意味着在调用 setTimeout()的线程终止之前,无法执行 A

What happens when you execute the above code is that the lexical parser first hoists the functions to the top of the code. Then the invocation of B() happens, followed by all synchronous code afterwords because JS is single-threaded. This means that A cannot be executed until the thread that called setTimeout() has terminated.

仅当所有同步代码完成并且经过3秒后,您才能调用 A()

Only when all synchronous code is finished and 3 seconds have passed will you get invocation of A().

通常,每当您编写一些代码来接收来自服务器的数据或当用户单击鼠标时做出响应时,该代码都是异步的。它在发生任何事情时执行。

In general, anytime you write some code to react when data from the server is received or when the user clicks the mouse, that code is asynchronous. It gets executed when something happens.

@Pointy 在评论中指出,这种异步行为本身并不是JavaScript的直接功能。

As @Pointy pointed out in the comments, this asynchronous behavior isn't a direct feature of JavaScript on its own. It usually comes from interaction with the system JS is running in and the events that system sends (user interacting with the browser or the operating system interacting with something like NodeJS)

这篇关于JavaScript中的异步行为和回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆