Heim > Web-Frontend > js-Tutorial > Hauptteil

Detaillierte Erläuterung der Callback-Funktionen in JavaScript

青灯夜游
Freigeben: 2020-12-14 17:56:33
nach vorne
4279 Leute haben es durchsucht

Detaillierte Erläuterung der Callback-Funktionen in JavaScript

JavaScript Callback Funktionen sind ein wichtiges Konzept, das Sie verstehen müssen, um ein erfolgreicher JavaScript-Entwickler zu sein. Aber ich glaube, dass Sie nach der Lektüre dieses Artikels in der Lage sein werden, alle Hindernisse zu überwinden, mit denen Sie vor der Verwendung von Rückrufmethoden konfrontiert waren.

Bevor wir beginnen, müssen wir zunächst sicherstellen, dass unser Verständnis der Funktionen solide ist.

Kurzübersicht: JavaScript-Funktionen

Was sind Funktionen?

Eine Funktion ist ein logischer Baustein mit einer Reihe von Code darin, um eine bestimmte Aufgabe auszuführen. Mit Funktionen können Sie Code tatsächlich besser organisiert schreiben, um das Debuggen und die Wartung zu vereinfachen. Funktionen ermöglichen auch die Wiederverwendung von Code.

Sie müssen die Funktion nur einmal definieren und bei Bedarf aufrufen, anstatt immer wieder denselben Code zu schreiben.

Deklarieren einer Funktion

Nun sehen wir uns an, wie man eine Funktion in Javascript deklariert.

  1. Verwendung des Funktionskonstruktors: Bei dieser Methode wird die Funktion mit Hilfe des Konstruktors „Funktion“ erstellt. Technisch gesehen ist diese Methode weniger effizient als die Verwendung der Funktionsausdruckssyntax und der Funktionsdeklarationsanweisungssyntax zum Deklarieren von Funktionen.

  2. Verwenden Sie Funktionsausdrücke: Normalerweise ist diese Methode dieselbe wie die Variablenzuweisung. Kurz gesagt, der Funktionskörper wird als Ausdruck behandelt und dieser Ausdruck wird einer Variablen zugewiesen. Mit dieser Syntax definierte Funktionen können benannte oder anonyme Funktionen sein.

    Eine Funktion ohne Namen wird als anonyme Funktion bezeichnet. Eine anonyme Funktion ist selbstaufrufend, das heißt, sie ruft sich automatisch selbst auf. Dieses Verhalten wird auch als sofort aufgerufener Funktionsausdruck (IIFE) bezeichnet.

  3. Funktionsdeklaration verwenden: Diese Methode ist die in JavaScript häufig verwendete Old-School-Methode. Nach dem Schlüsselwort „function“ müssen Sie den Namen der Funktion angeben. Wenn die Funktion später mehrere Argumente oder Argumente akzeptiert, müssen diese ebenfalls erwähnt werden. Obwohl dieser Teil völlig optional ist.

    Im Funktionskörper muss die Funktion einen Wert an den Aufrufer zurückgeben. Die Funktion wird nicht mehr ausgeführt, wenn eine Return-Anweisung auftritt. Innerhalb der Funktion fungieren Parameter als lokale Variablen.

    In ähnlicher Weise sind Variablen, die innerhalb einer Funktion deklariert werden, lokale Variablen dieser Funktion. Auf lokale Variablen kann nur innerhalb dieser Funktion zugegriffen werden, sodass Variablen mit demselben Namen problemlos in verschiedenen Funktionen verwendet werden können.

Eine Funktion aufrufen

Die zuvor deklarierte Funktion wird in einer der folgenden Situationen aufgerufen:

  • Wenn ein Ereignis eintritt, klickt der Benutzer beispielsweise auf eine Schaltfläche oder der Benutzer wählt eine Option aus einer Dropdown-Liste aus. Down-Liste usw. .
  • Beim Aufrufen der Funktion über Javascript-Code.
  • Diese Funktion kann automatisch aufgerufen werden, was wir in anonymen Funktionsausdrücken besprochen haben. Der Operator

() ruft diese Funktion auf. () 运算符调用该函数。

什么是回调函数?

按照 MDN 的描述:回调函数是作为参数传给另一个函数的函数,然后通过在外部函数内部调用该回调函数以完成某种操作

让我用人话解释一下,回调函数是一个函数,将会在另一个函数完成执行后立即执行。回调函数是一个作为参数传给另一个 JavaScript 函数的函数。这个回调函数会在传给的函数内部执行。

在 JavaScript 中函数被看作是一类对象。对于一类对象,我们的意思是指数字、函数或变量可以与语言中的其他实体相同。作为一类对象,可以将函数作为变量传给其他函数,也可以从其他函数中返回这些函数。

可以执行这种操作的函数被称为高阶函数。回调函数实际上是一种模式。 “模式”一词表示解决软件开发中常见问题的某种行之有效的方法。最好将回调函数作为回调模式去使用。

为什么我们需要回调

客户端 JavaScript 在浏览器中运行,并且浏览器的主进程是单线程事件循环。如果我们尝试在单线程事件循环中执行长时间运行的操作,则会阻止该过程。从技术上讲这是不好的,因为过程在等待操作完成时会停止处理其他事件。

例如,alert

Was ist eine Rückruffunktion?

Gemäß der MDN-Beschreibung: Eine Callback-Funktion ist eine Funktion, die als Parameter an eine andere Funktion übergeben wird und dann die Callback-Funktion innerhalb der externen Funktion aufgerufen wird, um einen bestimmten Vorgang abzuschließen.

Detaillierte Erläuterung der Callback-Funktionen in JavaScriptLassen Sie es mich in menschlichen Begriffen erklären: Eine Callback-Funktion ist eine Funktion, die ausgeführt wird, sobald eine andere Funktion die Ausführung abschließt. Eine Callback-Funktion ist eine Funktion, die als Parameter an eine andere JavaScript-Funktion übergeben wird. Diese Rückruffunktion wird innerhalb der übergebenen Funktion ausgeführt.

🎜In JavaScript werden Funktionen als Objekttyp betrachtet. Mit einer Klasse von Objekten meinen wir, dass eine Zahl, Funktion oder Variable mit anderen Entitäten in der Sprache identisch sein kann. Als Objektklasse können Funktionen als Variablen an andere Funktionen übergeben und von anderen Funktionen zurückgegeben werden. 🎜🎜Funktionen, die diese Art von Operation ausführen können, werden als Funktionen höherer Ordnung bezeichnet. Rückruffunktionen sind eigentlich ein Muster. Das Wort „Muster“ bezieht sich auf einen bestimmten bewährten Ansatz zur Lösung häufiger Probleme in der Softwareentwicklung. Am besten verwenden Sie die Callback-Funktion als Callback-Muster. 🎜🎜Warum wir Rückrufe brauchen🎜🎜Client-JavaScript 🎜 läuft im Browser und der Hauptprozess des Browsers ist Single-Threaded Ereignisschleife🎜. Wenn wir versuchen, einen lang andauernden Vorgang in einer Single-Threaded-Ereignisschleife auszuführen, wird der Prozess blockiert. Technisch gesehen ist dies schlecht, da der Prozess die Verarbeitung anderer Ereignisse stoppt, während er auf den Abschluss des Vorgangs wartet. 🎜🎜Zum Beispiel gilt die alert-Anweisung als einer der Blockierungscodes in Javascript im Browser. Wenn Sie eine Warnung ausführen, können Sie erst dann mit dem Browser interagieren, wenn Sie das Warnungsdialogfenster schließen. Um zu verhindern, dass lang laufende Vorgänge blockiert werden, verwenden wir Rückrufe. 🎜🎜Lassen Sie uns etwas tiefer gehen, damit Sie genau wissen, in welchen Fällen Rückrufe verwendet werden. 🎜🎜🎜🎜

Im obigen Codeausschnitt wird zuerst die Funktion getMessage() und dann die Funktion displayMessage() ausgeführt. Beide zeigen eine Meldung im Konsolenfenster des Browsers an und beide werden sofort ausgeführt. getMessage()函数,然后执行 displayMessage() 。两者都在浏览器的控制台窗口中显示了一条消息,并且都立即执行。

在某些情况下,一些代码不会立即执行。例如,如果我们假设 getMessage() 函数执行 API 调用,则必须将请求发送到服务器并等待响应。这时我们应该如何处理呢?

如何使用回调函数

我认为与其告诉你 JavaScript 回调函数的语法,不如在前面的例子中实现回调函数更好。修改后的代码段显示在下面的截图中。

Detaillierte Erläuterung der Callback-Funktionen in JavaScript

为了使用回调函数,我们需要执行某种无法立即显示结果的任务。为了模拟这种行为,我们用 JavaScript 的 setTimeout() 函数。该函数会暂停两秒钟,然后在控制台窗口中显示消息“ Hi,there”。

“显示的消息”将被显示在浏览器的控制台窗口中。在这种情况下,首先,我们需要等待 getMessage() 函数。成功执行此函数后,再执行 displayMessage() 函数。

回调的工作方式

让我解释一下前面的例子在幕后发生的事。

从上一个例子可以看到,在 getMessage() 函数中,我们传递了两个参数。第一个参数是 msg 变量,该变量显示在浏览器的控制台窗口中,第二个参数是回调函数。

现在,你可能想知道为什么将回调函数作为参数进行传递 —— 要实现回调函数,我们必须将一个函数作为参数传给另一个函数。

getMessage() 完成任务后,我们将调用回调函数。之后,当调用 getMessage() 函数时,将引用传给displayMessage() 函数,该函数就是回调函数。

注意,当调用 getMessage() 函数时,我们仅将其引用传给 displayMessage() 函数。这就是为什么你不会在它旁边看到函数调用运算符,也就是() 符号。

Javascript 回调是异步的吗?

JavaScript 被认为是单线程脚本语言。单线程是指 JavaScript 一次执行一个代码块。当 JavaScript 忙于执行一个块时,它不可能移到下一个块。

换句话说,我们可以认为 JavaScript 代码本质上总是阻塞的。但是这种阻塞性使我们无法在某些情况下编写代码,因为在这些情况下我们没有办法在执行某些特定任务后立即得到结果。

我谈论的任务包括以下情况:

  • 通过对某些端点进行 API 调用来获取数据。
  • 通过发送网络请求从远程服务器获取一些资源(例如,文本文件、图像文件、二进制文件等)。

为了处理这些情况,必须编写异步代码,而回调函数是处理这些情况的一种方法。所以从本质上上说,回调函数是异步的。

Javascript 回调地狱

当多个异步函数一个接一个地执行时,会产生回调地狱。它也被称为厄运金字塔。

假设你要获取所有 Github 用户的列表。然后在用户中搜索 JavaScript 库的主要贡献者。再然后,你想要在用户中获取姓名为 John 的人员的详细信息。

为了在回调的帮助下实现这个功能,代码应该如下所示:

http.get('https://api.github.com/users', function(users) {
  /* Display all users */
  console.log(users);
  http.get('https://api.github.com/repos/javascript/contributors?q=contributions&order=desc', 
  function(contributors) {
  /* Display all top contributors */
    console.log(contributors);
    http.get('https://api.github.com/users/Jhon', function(userData) {
    /* Display user with username 'Jhon' */
      console.log(userData);
    });
  });
});
Nach dem Login kopieren

从上面的代码片段中,你可以看到代码变得更加难以理解,以及难以维护和修改。这是由回调函数的嵌套而引发的。

如何避免回调地狱?

可以使用多种技术来避免回调地狱,如下所示。

  1. 使用promise
  2. 借助 async-await
  3. 使用 async.js 库

使用 Async.js 库

让我们谈谈怎样用 async.js 库避免回调地狱。

根据 async.js 官方网站的描述:Async 是一个工具模块,它提供了直接、强大的函数来使用异步 JavaScript

Async.js 总共提供约 70 个函数。现在,我们将仅讨论其中两个,即 async.waterfall()async.series()

In einigen Fällen werden einige Codes nicht sofort ausgeführt. Wenn wir beispielsweise davon ausgehen, dass die Funktion getMessage() einen API-Aufruf ausführt, muss sie die Anfrage an den Server senden und auf die Antwort warten. Wie sollen wir damit umgehen?

So verwenden Sie Rückruffunktionen

Anstatt Ihnen die Syntax von JavaScript-Rückruffunktionen zu erklären, wäre es meiner Meinung nach besser, die Rückruffunktion im vorherigen Beispiel zu implementieren. Der geänderte Codeausschnitt wird im folgenden Screenshot angezeigt.

Detaillierte Erläuterung der Callback-Funktionen in JavaScript🎜🎜Für Mithilfe von Rückruffunktionen müssen wir eine Aufgabe ausführen, bei der das Ergebnis nicht sofort angezeigt werden kann. Um dieses Verhalten zu simulieren, verwenden wir die JavaScript-Funktion setTimeout(). Die Funktion pausiert für zwei Sekunden und zeigt dann die Meldung „Hallo, da“ im Konsolenfenster an. 🎜🎜Die „angezeigte Nachricht“ wird im Konsolenfenster des Browsers angezeigt. In diesem Fall müssen wir zunächst auf die Funktion getMessage() warten. Nachdem Sie diese Funktion erfolgreich ausgeführt haben, führen Sie die Funktion displayMessage() aus. 🎜

Wie Rückrufe funktionieren

🎜Lassen Sie mich erklären, was im vorherigen Beispiel hinter den Kulissen passiert. 🎜🎜Wie Sie dem vorherigen Beispiel entnehmen können, übergeben wir in der Funktion getMessage() zwei Parameter. Der erste Parameter ist die Variable msg, die im Konsolenfenster des Browsers angezeigt wird, und der zweite Parameter ist die Rückruffunktion. 🎜🎜Jetzt fragen Sie sich vielleicht, warum Callback-Funktionen als Parameter übergeben werden – um Callback-Funktionen zu implementieren, müssen wir eine Funktion als Parameter an eine andere Funktion übergeben. 🎜🎜Nachdem getMessage() seine Aufgabe abgeschlossen hat, rufen wir die Rückruffunktion auf. Wenn später die Funktion getMessage() aufgerufen wird, wird der Verweis an die Funktion displayMessage() übergeben, bei der es sich um die Rückruffunktion handelt. 🎜🎜Beachten Sie, dass wir beim Aufruf der Funktion getMessage() nur deren Referenz an die Funktion displayMessage() übergeben. Aus diesem Grund wird der Funktionsaufrufoperator, das Symbol (), daneben nicht angezeigt. 🎜

Sind Javascript-Rückrufe asynchron?

🎜JavaScript gilt als Single-Threaded-Skriptsprache. Single-Threading bedeutet, dass JavaScript jeweils einen Codeblock ausführt. Während JavaScript mit der Ausführung eines Blocks beschäftigt ist, kann es nicht zum nächsten Block wechseln. 🎜🎜Mit anderen Worten: Wir können uns JavaScript-Code so vorstellen, dass er von Natur aus immer blockiert. Diese blockierende Natur hält uns jedoch in manchen Fällen davon ab, Code zu schreiben, wenn wir nach der Ausführung einer bestimmten Aufgabe keine Möglichkeit haben, das Ergebnis sofort zu erhalten. 🎜🎜Zu den Aufgaben, über die ich spreche, gehören Situationen wie: 🎜
  • Abrufen von Daten durch API-Aufrufe an einige Endpunkte.
  • Rufen Sie einige Ressourcen (z. B. Textdateien, Bilddateien, Binärdateien usw.) von einem Remote-Server ab, indem Sie eine Netzwerkanfrage senden.
🎜Um mit diesen Situationen umzugehen, muss asynchroner Code geschrieben werden, und Rückruffunktionen sind eine Möglichkeit, mit diesen Situationen umzugehen. Rückruffunktionen sind also im Wesentlichen asynchron. 🎜

Javascript Callback Hell

🎜Callback Hell tritt auf, wenn mehrere asynchrone Funktionen nacheinander ausgeführt werden. Sie ist auch als Pyramide des Untergangs bekannt. 🎜🎜Angenommen, Sie möchten eine Liste aller Github-Benutzer erhalten. Suchen Sie dann unter den Benutzern nach Top-Mitwirkenden für JavaScript-Bibliotheken. Anschließend möchten Sie die Details der Person namens John unter den Benutzern abrufen. 🎜🎜Um diese Funktionalität mit Hilfe von Rückrufen zu implementieren, sollte der Code so aussehen: 🎜
var async = require('async');
async.waterfall([
    function(callback) {
      /*  
        Here, the first argument value is null, it indicates that
        the next function will be executed from the array of functions.
        If the value was true or any string then final callback function
        will be executed, other remaining functions in the array 
        will not be executed.
      */
        callback(null, 'one', 'two');
    },
    function(param1, param2, callback) {
        // param1 now equals 'one' and param2 now equals 'two'
        callback(null, 'three');
    },
    function(param1, callback) {
        // param1 now equals 'three'
        callback(null, 'done');
    }
], function (err, result) {
    /*
      This is the final callback function.
      result now equals 'done'
    */
});
Nach dem Login kopieren
Nach dem Login kopieren
🎜 Aus dem obigen Codeausschnitt können Sie ersehen, dass der Code schwieriger zu verstehen sowie schwieriger zu warten und zu ändern ist. Dies wird durch die Verschachtelung von Callback-Funktionen verursacht. 🎜

Wie vermeide ich die Rückrufhölle?

🎜Eine Reihe von Techniken können verwendet werden, um die Rückrufhölle zu vermeiden, wie unten gezeigt. 🎜
  1. Versprechen verwenden
  2. Mit async-await
  3. Async.js-Bibliothek verwenden

Async.js-Bibliothek verwenden li> h3>🎜Lassen Sie uns darüber sprechen, wie Sie mithilfe der async.js-Bibliothek die Callback-Hölle vermeiden können. 🎜🎜Laut der Beschreibung der offiziellen Website von async.js: Async ist ein Toolmodul, das direkte und leistungsstarke Funktionen zur Verwendung von asynchronem JavaScript bereitstellt. 🎜🎜Async.js bietet insgesamt etwa 70 Funktionen. Im Moment werden wir nur zwei davon besprechen, nämlich async.waterfall() und async.series(). 🎜🎜async.waterfall()🎜🎜Diese Funktion ist sehr nützlich, wenn Sie bestimmte Aufgaben nacheinander ausführen und dann die Ergebnisse der vorherigen Aufgabe an die nächste übergeben möchten. Es benötigt ein „task“-Array von Funktionen und eine letzte „Callback“-Funktion, die aufgerufen wird, nachdem alle Funktionen im „task“-Array abgeschlossen sind oder nachdem der „callback“ mit einem Fehlerobjekt aufgerufen wurde. 🎜
var async = require('async');
async.waterfall([
    function(callback) {
      /*  
        Here, the first argument value is null, it indicates that
        the next function will be executed from the array of functions.
        If the value was true or any string then final callback function
        will be executed, other remaining functions in the array 
        will not be executed.
      */
        callback(null, 'one', 'two');
    },
    function(param1, param2, callback) {
        // param1 now equals 'one' and param2 now equals 'two'
        callback(null, 'three');
    },
    function(param1, callback) {
        // param1 now equals 'three'
        callback(null, 'done');
    }
], function (err, result) {
    /*
      This is the final callback function.
      result now equals 'done'
    */
});
Nach dem Login kopieren
Nach dem Login kopieren

async.series()

当你要运行一个函数然后在所有函数成功执行后需要获取结果时,它很有用。  async.waterfall()async.series() 之间的主要区别在于, async.series() 不会将数据从一个函数传递到另一个函数。

async.series([
    function(callback) {
        // do some stuff ...
        callback(null, 'one');
    },
    function(callback) {
        // do some more stuff ...
        callback(null, 'two');
    }
],
// optional callback
function(err, results) {
    // results is now equal to ['one', 'two']
});
Nach dem Login kopieren

Javascript 回调与闭包

闭包

用技术术语来说,闭包是捆绑在一起的函数的组合,引用了其周围的状态。

简而言之,闭包允许从内部函数访问外部函数的作用域。

要使用闭包,我们需要在一个函数内部定义另一个函数。然后,我们需要将其返回或传给另一个函数。

回调

从概念上讲,回调类似于闭包。回调基本上是把一个函数作为另一个函数的用法。

最后的话

希望本文能消除你对 javascript 回调函数的所有疑问。如果你觉得这篇文章有帮助,请与他人分享。

原文地址:https://dzone.com/articles/javascript-callback-functions-in-depth-guide-for-2

为了保证的可读性,本文采用意译而非直译。

更多编程相关知识,请访问:编程教学!!

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der Callback-Funktionen in JavaScript. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:segmentfault.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage