ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScriptのコールバック関数の詳しい説明

JavaScriptのコールバック関数の詳しい説明

青灯夜游
青灯夜游転載
2020-12-14 17:56:334262ブラウズ

JavaScriptのコールバック関数の詳しい説明

#JavaScript コールバック 関数は、JavaScript 開発者として成功するために理解しておく必要がある重要な概念です。しかし、この記事を読めば、コールバック メソッドを使用する前に直面していたすべての障害を克服できるようになると思います。

始める前に、まず機能についてしっかりと理解していることを確認する必要があります。

クイックレビュー: JavaScript 関数

関数とは何ですか?

関数は、特定のタスクを実行するための一連のコードを内部に持つ論理的な構成要素です。実際、関数を使用すると、デバッグとメンテナンスが容易になるように、より組織化された方法でコードを作成できます。関数を使用すると、コードを再利用することもできます。

同じコードを何度も記述するのではなく、関数を一度定義するだけで、必要に応じて呼び出すことができます。

関数の宣言

次に、JavaScript で関数を宣言する方法を見てみましょう。

  1. 関数のコンストラクターの使用: このメソッドでは、「関数」のコンストラクターを使用して関数を作成します。技術的に言えば、この方法は、関数式構文および関数宣言ステートメント構文を使用して関数を宣言するよりも効率が低くなります。

  2. 関数式を使用する: 通常、この方法は変数の代入と同じです。つまり、関数本体は式として扱われ、その式が変数に代入されます。この構文を使用して定義された関数は、名前付き関数または匿名関数にすることができます。

    名前のない関数は、匿名関数と呼ばれます。匿名関数は自己呼び出しです。つまり、それ自体が自動的に呼び出されます。この動作は、即時に呼び出される関数式 (

    IIFE) とも呼ばれます。

  3. 関数宣言を使用する: このメソッドは、JavaScript で一般的に使用される昔ながらのメソッドです。キーワード「function」の後に、関数の名前を指定する必要があります。後で、関数が複数の引数を受け入れる場合は、それらも指定する必要があります。ただし、この部分は完全にオプションです。 関数本体では、関数は呼び出し元に値を返す必要があります。この関数は、return ステートメントが検出されると実行を停止します。関数内では、パラメーターはローカル変数として機能します。

    同様に、関数内で宣言された変数は関数のローカル変数です。ローカル変数はその関数内でのみアクセスできるため、同じ名前の変数を別の関数で簡単に使用できます。

関数の呼び出し

以前に宣言した関数は、次のいずれかの状況で呼び出されます。

    イベントが発生したとき。 、ユーザーがボタンをクリックするか、ドロップダウン リストからオプションを選択するなどです。
  • JavaScript コードから関数を呼び出す場合。
  • この関数は自動的に呼び出すことができます。これについては、匿名関数式で説明しました。

() 演算子はこの関数を呼び出します。

コールバック関数とは何ですか?

MDN の説明によると:

コールバック関数は、パラメーターとして別の関数に渡される関数であり、そのコールバック関数は外部関数内で呼び出され、特定の操作を完了します

人間の言葉で説明しましょう。コールバック関数は、別の関数の実行が完了するとすぐに実行される関数です。コールバック関数は、別の JavaScript 関数にパラメーターとして渡される関数です。このコールバック関数は、渡された関数内で実行されます。

JavaScript では、関数はオブジェクトの一種とみなされます。オブジェクトのクラスとは、数値、関数、または変数が言語内の他のエンティティと同じである可能性があることを意味します。オブジェクトのクラスとして、関数を変数として他の関数に渡したり、他の関数から返すことができます。

この操作を実行できる関数を高階関数と呼びます。コールバック関数は実際にはパターンです。 「パターン」という言葉は、ソフトウェア開発における一般的な問題を解決するための、実証済みのアプローチを指します。コールバック関数をコールバック パターンとして使用するのが最善です。

コールバックが必要な理由

クライアントサイド JavaScript はブラウザ内で実行され、ブラウザのメイン プロセスはシングルスレッドの イベント ループです。シングルスレッドのイベント ループで長時間実行操作を実行しようとすると、プロセスはブロックされます。操作が完了するまでプロセスが他のイベントの処理を停止するため、技術的にはこれは問題です。

たとえば、

alert ステートメントは、ブラウザーの JavaScript のブロック コードの 1 つとみなされます。アラートを実行すると、アラート ダイアログ ウィンドウを閉じるまでブラウザで操作できなくなります。長時間実行される操作がブロックされるのを防ぐために、コールバックを使用します。

どのような場合にコールバックが使用されるかを正確に理解できるように、もう少し詳しく見てみましょう。

JavaScriptのコールバック関数の詳しい説明

上記のコード スニペットでは、getMessage() 関数が最初に実行され、次に displayMessage() が実行されます。どちらもブラウザのコンソール ウィンドウにメッセージを表示し、すぐに実行されます。

場合によっては、一部のコードがすぐに実行されないことがあります。たとえば、getMessage() 関数が API 呼び出しを実行すると仮定すると、リクエストはサーバーに送信され、応答を待つ必要があります。これにどう対処すべきでしょうか?

コールバック関数の使用方法

JavaScript コールバック関数の構文を説明する代わりに、前の例でコールバック関数を実装した方がよいと思います。変更されたコード スニペットを以下のスクリーンショットに示します。

JavaScriptのコールバック関数の詳しい説明

#コールバック関数を使用するには、結果をすぐに表示できない何らかのタスクを実行する必要があります。この動作をシミュレートするには、JavaScript の setTimeout() 関数を使用します。関数は 2 秒間停止し、コンソール ウィンドウに「こんにちは」というメッセージが表示されます。

「表示メッセージ」はブラウザのコンソールウィンドウに表示されます。この場合、まず getMessage() 関数を待つ必要があります。この関数が正常に実行された後、displayMessage() 関数を実行します。

コールバックの仕組み

前の例の舞台裏で何が起こっているのか説明しましょう。

前の例からわかるように、getMessage() 関数では 2 つのパラメーターを渡しました。最初のパラメータはブラウザのコンソール ウィンドウに表示される msg 変数で、2 番目のパラメータはコールバック関数です。

ここで、なぜコールバック関数がパラメータとして渡されるのか疑問に思われるかもしれません。コールバック関数を実装するには、関数をパラメータとして別の関数に渡す必要があります。

getMessage() がタスクを完了した後、コールバック関数を呼び出します。その後、getMessage() 関数が呼び出されるとき、参照はコールバック関数である displayMessage() 関数に渡されます。

getMessage() 関数を呼び出すときは、その参照を displayMessage() 関数に渡すだけであることに注意してください。その隣に関数呼び出し演算子である () 記号が表示されないのはそのためです。

JavaScript コールバックは非同期ですか?

JavaScript はシングルスレッドのスクリプト言語とみなされます。シングル スレッドとは、JavaScript が一度に 1 つのコード ブロックを実行することを意味します。 JavaScript が 1 つのブロックの実行でビジー状態の間は、次のブロックに移動できません。

言い換えれば、JavaScript コードは本質的に常にブロックしていると考えることができます。ただし、このブロッキングの性質により、特定のタスクを実行した直後に結果を取得する方法がない場合、コードを作成できなくなります。

私が話しているタスクには、次のような状況が含まれます。

  • いくつかのエンドポイントに対して API 呼び出しを行ってデータを取得する。
  • ネットワーク要求を送信して、リモート サーバーからリソース (テキスト ファイル、画像ファイル、バイナリ ファイルなど) を取得します。

これらの状況に対処するには、非同期コードを記述する必要があります。コールバック関数は、これらの状況に対処する 1 つの方法です。したがって、本質的に、コールバック関数は非同期です。

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);
    });
  });
});

上記のコード スニペットから、コードがさらに理解しにくくなり、理解しにくくなることがわかります。メンテナンスと修正。これはコールバック関数のネストが原因で発生します。

コールバック地獄を回避するにはどうすればよいですか?

以下に示すように、コールバック 地獄を回避するためにいくつかの手法を使用できます。

    #promise を使用する
  1. async-await を使用する
  2. async.js ライブラリを使用する
Async.js ライブラリを使用する

async.js ライブラリを使用してコールバック地獄を回避する方法について話しましょう。

async.js 公式 Web サイトによると:

Async は、非同期 JavaScript を使用するための直接的で強力な機能を提供するツール モジュールです。 Async.js は合計で約 70 個の関数を提供します。ここでは、そのうちの 2 つ、

async.waterfall()

async.series() についてのみ説明します。 async.waterfall()

この関数は、特定のタスクを次々に実行し、前のタスクの結果を次のタスクに渡したい場合に便利です。これは、関数の「タスク」配列と、「タスク」配列内のすべての関数が完了した後、または「コールバック」がエラー オブジェクトで呼び出された後に呼び出される最後の「コールバック」関数を受け取ります。

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'
    */
});

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']
});

Javascript 回调与闭包

闭包

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

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

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

回调

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

最后的话

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

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

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

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

以上がJavaScriptのコールバック関数の詳しい説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。