使用Minions解释JavaScript回调

 2023-09-06 阅读 22 评论 0

摘要:by Kevin Kononenko 凯文科诺年科(Kevin Kononenko) 使用Minions解释JavaScript回调 (JavaScript Callbacks Explained Using Minions) Callbacks. Asynchronous. Non-blocking. 回调。 异步。 不阻塞。 These JavaScript concepts are making you tear your hair out. 这些Ja

by Kevin Kononenko

凯文·科诺年科(Kevin Kononenko)

使用Minions解释JavaScript回调 (JavaScript Callbacks Explained Using Minions)

Callbacks. Asynchronous. Non-blocking.

回调。 异步。 不阻塞。

These JavaScript concepts are making you tear your hair out.

这些JavaScript概念使您不知所措。

I was there too at one point. I needed an analogy to make these abstract concepts become easy enough that I could teach them to someone else (and prove that I truly understood them myself).

我也在那里。 我需要一个类比来使这些抽象概念变得足够容易,以便我可以将它们教给其他人(并证明我自己真正理解了它们)。

Sure, there were a few good tutorials out there (like this one and this one). But every tutorial instantly started with complex terms.

当然,那里有一些不错的教程(例如本教程和本教程)。 但是每个教程都立即以复杂的术语开始。

I needed something I could connect to.

我需要可以连接的东西。

I needed Minions.

我需要奴才。

So, I am going to use these lovable minions to explain callbacks. In this little analogy, you are their master. You can order your army of minions to do whatever you want in your code. But:

因此,我将使用这些可爱的奴才来解释回调。 以此为例,您就是他们的主人。 您可以命令您的爪牙军在代码中做任何您想做的事情。 但:

  1. There is only one master.

    只有一位主人。
  2. The minions must take orders from you. They cannot make their own decisions.

    奴才必须接受你的命令。 他们无法做出自己的决定。

Minion. Noun. Someone who is not powerful or important and who obeys the orders of a powerful leader or boss.

奴才。 名词。 没有权力或重要性的人,服从强大的领导者或老板的命令。

主要概念 (The Main Concept)

Any time you see “function()” in your jQuery or JavaScript inside another function or method, imagine it instead says “minion()”. You can’t actually type this because the JavaScript language does not recognize “minion()” (unless you create an actual function called “minion”). But that is now what you are doing when you create a callback function- giving orders to minions.

每当您在jQuery或JavaScript中的另一个函数或方法中看到“ function()”时,请想象它改为显示“ minion()”。 您实际上无法键入此内容,因为JavaScript语言无法识别“ minion()”(除非您创建一个称为“ minion”的实际函数)。 但这就是创建回调函数(将命令分配给minions)时所要做的。

An example with a minion ready for orders

一个小兵准备下订单的例子

function myFunction(input, function(err, data){
});

This is basically saying…

这基本上是在说……

function myFunction(input, minion(err, data){
});

An example with just a plain old function, no minion available:

一个仅具有普通旧功能而没有奴才可用的示例:

function addOne(data){:
return data++;
};

jQuery示例 (jQuery Examples)

超级基础 (Super Basic)

So remember, this is kind of like saying:

因此请记住,这有点像在说:

What is a callback doing here?

回调在这里做什么?

You, the master/boss, have to watch for events across the entire file, and potentially multiple files. You ain’t got time for some little jQuery click handler! So, you delegate it to a minion, as shown in example 2.

您,主人/老板,必须注意整个文件,甚至可能是多个文件的事件。 您没有时间使用一些jQuery单击处理程序! 因此,将其委派给一个奴才,如示例2所示。

Now, this is a simple function, and you could probably do it yourself, but what if it was 20 lines long? You can’t be distracted with a 20 line long function when you need to be taking other instructions from the user as well!

现在,这是一个简单的函数,您可能可以自己完成,但是如果它长20行呢? 当您还需要从用户那里获取其他说明时,您也不会因20行长的功能而分心!

So, you tell a minion to do it on line 1 after the user clicks ‘.myButton’. This frees you up to give other orders to more minions- much more efficient than doing it yourself and making other important functions wait.

因此,您告诉小兵在用户单击“ .myButton”后在第1行执行此操作。 这样您就可以腾出时间来将其他命令分配给更多的奴才,这比自己完成任务和等待其他重要功能要高效得多。

动画范例 (Animation Example)

Let’s look at a show/hide sequence to really highlight the importance of these minions.

让我们看一下显示/隐藏序列,以真正突出显示这些仆从的重要性。

In this example, if you read the code in order and didn’t have minions at your side, the console would log “One”, “Two”, “Three”. BUT, you have minions, and the console will actually log “One”, “Three”, “Two” in this case. Here is why:

在此示例中,如果您按顺序阅读代码,但身边没有奴才,则控制台将记录“一个”,“两个”,“三个”。 但是,您有小兵,在这种情况下,控制台实际上会记录“一个”,“三个”,“两个”。 原因如下:

Line 1: You ordered your first minion, and went on to watch for other events triggered by the user.

第1行:您订购了第一个小兵,然后继续观察用户触发的其他事件。

Line 2: Your first minion read the console statement, then went on to line 3.

第2行:您的第一个奴才阅读了console语句,然后继续进行第3行。

Line 3: Minion 1 brought another minion in to help: Minion 2. Specifically, Minion 2 must sit there and wait for the show() method to finish before continuing on its instructions. So now you have two minions working for you, simultaneously trying to finish their work within the function as quickly as possible!

第3行:Minion 1 带来了另一个minion来提供帮助 :Minion2。具体地说,Minion 2必须坐在那里,等待show()方法完成,然后再继续执行其指令。 因此,现在您有两个小兵为您工作,同时试图尽快完成他们在功能中的工作!

Minion 1 now jumps all the way down to line 7, since Minion 2 needs to accomplish lines 4–5. It reads the console.log statement, and is done- no more callbacks, no more work to do. Minion 2, fractions of a millisecond behind, reads console.log(“Two”) and then makes sure the child div is shown in line 5. Now that minion is done too.

奴才1现在一直跳到第7行,因为奴才2需要完成第4-5行。 它读取console.log语句并完成-不再有回调,也没有其他工作要做。 奴才2,小数点后一毫秒,读取console.log(“ Two”),然后确保在第5行显示子div。现在,奴才也已完成。

Here is an incredibly important lesson: Your callback functions define the order that different actions occur. Think of how powerful this is: you can ensure that one action happens after another, as opposed to being forced to create one long, consecutive string of commands. This allows for much more flexibility. If you couldn’t force minions to carry out your orders, you would have to do it all yourself.

这是非常重要的一课: 您的回调函数定义了不同操作发生的顺序 。 想想这有多强大:您可以确保一个动作在另一个动作之后发生,而不是被迫创建一个长而连续的命令字符串。 这允许更大的灵活性。 如果您不能强迫小兵执行订单,则必须自己完成。

The jQuery logic above only works with callbacks, in fact. In line 5, showing the child div must happen after showing the parent div. You cannot show a child div if the parent div is hidden. The only way to guarantee that the child div will get shown after the parent div is a callback.

实际上,上面的jQuery逻辑仅适用于回调。 在第5行中,显示子div 必须在显示父div之后发生。 如果父div隐藏, 则无法显示子div 。 保证子div在父div 之后显示的唯一方法是回调。

If there were no callbacks in the above example, line 5 could cause an error because the show() method in line 3 had not completed yet. Minion 1, who started at line 1, passes the task along of completing lines 4–5 to Minion 2 so Minion 2 can wait on the completion of the show() method in line 3 before starting work on 4–5. This guarantees Minion 2 will start and finish the second show() statement after the first show() statement is complete. Minion 1 then moves on to the rest of the outer function, without needing to wait.

如果上面的示例中没有回调,则第5行可能会导致错误,因为第3行中的show()方法尚未完成。 从第1行开始的Minion 1将任务完成4-5行传递给Minion 2,因此Minion 2在第 4-5 开始工作之前可以等待第3行中show()方法的完成 。 这样可以保证Minion 2将在第一个show()语句完成之后开始并结束第二个show()语句。 奴才1然后继续进行外部功能的其余部分,而无需等待。

纯JavaScript和Node.js示例 (Plain JavaScript and Node.js Examples)

使用参数和回调 (Using Parameters and Callbacks)

All right, a little more complicated example! Lines 2 and 14 are just declaring functions, so let’s skip down to line 20 where the action actually starts. I called the speakOrders function with two parameters. The first is an object with the statements I eventually want my minion to report. The second is a callback- a function named reportOrders in this case.

好吧,稍微复杂一点的例子! 第2和14行只是声明函数,因此让我们跳到第20行,该操作实际上开始了。 我用两个参数调用了speakOrders函数。 第一个是带有我最终希望我的小仆报告的陈述的对象。 第二个是回调-在本例中为一个名为reportOrders的函数。

Your minion cannot reportOrders until you have spoken the orders! So that is how these functions get executed. On line 20, I called speakOrders with instructions. So I jump up to line 14 to see what the speakOrders function should do. Apparently, it just feeds these instructions into the callback function.

您的仆从无法说出订单,直到您说出订单! 这就是这些函数的执行方式。 在第20行,我通过指令调用了speakOrders。 因此,我跳到第14行,看看speakOrders函数应该做什么。 显然,它只是将这些指令提供给回调函数。

On line 20, I declared the callback function to be reportOrders, but it could be anything! memorizeOrders, tellMySpouse, any other function you name. It is standard to use “callback” in your function declaration on line 14 to ensure other people looking at your code know that a callback will need to happen. Could be any other word though! Here is the example restated, minion-ified.

在第20行,我将回调函数声明为reportOrders,但可以是任何东西! memorizeOrders,tellMySpouse以及您命名的任何其他函数。 通常在第14行的函数声明中使用“回调”,以确保其他在查看您代码的人都知道需要进行回调。 可以是其他任何单词! 这是经过重述,小事化的示例。

There is only one minion in this entire snippet- on lines 14–15, replacing “callback”.

在第14-15行的整个代码片段中,只有一个奴才,代替了“回调”。

Line 20: I call speakOrders. I pass along the orders- the object with name and specialty. The second parameter could be anything- a string, a function, or something else.

第20行:我称为speakOrders。 我通过订单-具有名称和专业的对象。 第二个参数可以是任何东西-字符串,函数或其他东西。

Line 14–15: I define that the second parameter actually must be a callback function since on line 15, the minion is followed by (). So, any time we call the speakOrders function, we now know that the second parameter will be a function. That is reportOrders, in this case.

第14-15行:我定义第二个参数实际上必须是一个回调函数,因为在第15行中,minion后跟()。 因此,无论何时调用speakOrders函数,我们现在都知道第二个参数将是一个函数。 在这种情况下,就是reportOrders。

Line 15: I know from line 20 that my minion will need to carry out the reportOrders function. It receives the orders parameter, an object. It needs these instructions to successfully report.

第15行:从第20行知道,我的奴才需要执行reportOrders函数。 它接收orders参数,即一个对象。 它需要这些说明才能成功报告。

Line 2: The orders variable from line 15 is now referenced as minionOrders within the function. The reportOrder function finishes, and the name and specialty are reported back.

第2行:第15行的order变量现在在函数中被称为minionOrders。 reportOrder函数完成,并且名称和专业被报告回来。

Callbacks are important here to clearly trace a path that the object must follow. Without callbacks, this would be a bunch of code in one order with little flexibility to reuse functions and change around order.

此处的回调很重要,以便清楚地跟踪对象必须遵循的路径 。 如果没有回调,这将是一堆代码,而且几乎没有灵活性来重用函数和更改顺序。

Node.js (Node.js)

Take a look at the following example which uses Express and the request module. This is the toughest one yet!

看一下下面的示例,该示例使用Express和request模块 。 这是最艰难的!

Let’s imagine the user just performed a GET request along the /storeData route. So we begin at line 9. This example includes callback use cases from all 3 the previous examples.

假设用户只是沿着/ storeData路由执行了GET请求。 因此,我们从第9行开始。该示例包括前面示例中所有3个示例的回调用例。

  1. There is a callback within a method at line 9, similar to the jQuery click handler example.

    第9行的方法中有一个回调,类似于jQuery click handler示例。
  2. There is asynchronous execution at line 14, centered around a fake API request, similar to the jQuery animation example.

    第14行以假API请求为中心进行异步执行,类似于jQuery动画示例。
  3. There is a callback parameter declared in line 13, similar to the vanilla JS example.

    在第13行中声明了一个回调参数,类似于原始JS示例。

To make this as clear as possible, here is the minion-ified code, with minion numbers indicating the order they will get executed in.

为了使这一点尽可能清楚,这是小部分代码,小部分数字表示执行它们的顺序。

Line 9: User hits the route. You, the boss, order Minion 1 to get to work on your orders. It jumps down to line 10 and sees the readResult function. You can now wait for more cues from the user while your minions are at work.

第9行:用户点击路线。 您,老板,命令小黄人1开始处理您的订单。 它跳到第10行,并看到readResult函数。 现在,您的小兵在工作时可以等待用户的更多提示。

Line 14: Minion 1 sees the request call, performs it on the fake API, and orders Minion 2 to wait on the result. Minion 1 can move on to other work. Since there is no more, Minion 1 is relieved of duty.

第14行: Minion 1看到请求调用,在伪API上执行请求,并命令Minion 2等待结果。 奴才1可以继续其他工作。 由于没有更多内容,奴才1被解除职务。

Line 14: Minion 2 kicks into action when the request call is finished. It is now carrying three pieces of potentially important information from the route- err, response and body.

第14行:请求调用结束后,小仆2开始行动。 现在,它从路由,响应和正文中携带了三个潜在的重要信息。

Line 15–16: The global variable “results” is set to the body value. This global variable can now be used in other functions as well. Minion 2 tells Minion 3 that it is time to get to work on its instructions. Minion 3 originally received instructions from line 10, and had been waiting to complete them until it was called. Now is the time to complete logRes()!

15-16行 :全局变量“结果”设置为主体值。 现在,该全局变量也可以在其他函数中使用。 奴才2告诉奴才3,是时候开始对其指令进行操作了。 奴才3最初是从第10行接收到指令的,并且一直在等待完成直到被调用为止。 现在是时候完成logRes()了!

Line 5: And the instructions are… a console.log. That was disappointing. Anyway, Minion 3 is done now.

第5行 :说明是……console.log。 真令人失望。 无论如何,Minion 3现在就完成了。

So how the heck did Minion 3 get called after Minion 2?

那么,在《小黄人2》之后,《小黄人3》如何被召唤呢?

Some sort of Minion-ception?

某种奴才感觉?

If you go back to the Node Example 1 code, you will see that line 13 initializes a callback. That means every time the readResult() function is called, there must be a callback parameter. This sets the callback up for use later at line 16. At line 16, the callback has the ability to use the products of the API request on line 14 because the request call has a callback itself!

如果返回到Node Example 1代码,您将看到第13行初始化了一个回调。 这意味着每次调用readResult()函数时,都必须有一个回调参数。 这将设置回调以供稍后在第16行使用。在第16行,该回调具有在第14行使用API​​请求产品的能力,因为请求调用本身具有回调

Imagine if callback/minion3 was a line lower than line 17, outside the scope of the request call. First of all, that would make it Minion 2, since it would get executed before the request call finished. And, the results of the request call would not yet be available, which would make this entire function pretty pointless. The entire point is to do the request call then pass the results on.

试想一下,如果callback / minion3是低于第17行的行,则超出了请求调用的范围。 首先,这将使其成为Minion 2,因为它将在请求调用完成之前被执行。 而且,请求调用的结果尚不可用,这将使整个函数变得毫无意义。 整个过程就是进行请求调用,然后传递结果。

Again, the use of 2 separate callbacks in the readResult() function ensures that Minion 3 goes to work after the request is complete. Callbacks provide a level of control so you can determine this custom order.

同样,在readResult()函数中使用2个单独的回调可确保Minion 3在请求完成后开始工作。 回调提供一定程度的控制,因此您可以确定此自定义顺序。

结论 (Conclusion)

You are the minion master, with hordes of squealing little servants ready to do your bidding. If you can give them the right instructions, they can make your life so much easier. They do all the hard work, and let you listen to the user’s instructions.

您是奴才的主人,成群地尖叫着准备招募的小仆人。 如果您能给他们正确的指导,他们可以使您的生活变得更加轻松。 他们完成所有艰苦的工作,并让您听取用户的说明。

Did this help you? Let me know in the comments.

这对您有帮助吗? 在评论中让我知道。

翻译自: https://www.freecodecamp.org/news/javascript-callbacks-explained-using-minions-da272f4d9bcd/

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/1/8005.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息