ホームページ ウェブフロントエンド jsチュートリアル JavaScriptキュー機能とasynchronous_javascriptスキルの詳細説明

JavaScriptキュー機能とasynchronous_javascriptスキルの詳細説明

Jun 28, 2017 pm 01:21 PM
javascript js 詳しい説明

この記事では主に JavaScript キュー関数と非同期実行に関する情報を詳しく紹介します。興味のある方は参考にしてください。

編集者注: 他の人の JavaScript コードをレビューしているときに、同様のキューを見たことがあります。関数を理解していますが、これは関数が順番に呼び出されることを保証するためであることがわかりました。この記事を読んで、非同期実行などにも使えることが分かりました。

順番に呼び出す必要があるいくつかの関数 fn1、fn2、fn3 があるとします。もちろん、最も簡単な方法は次のとおりです。

fn1();
fn2();
fn3();
ログイン後にコピー

しかし、これらの関数は実行時に 1 つずつ追加されることがあり、いつ追加されるかはわかりません。このとき、関数を追加するときに、配列から関数を 1 つずつ取り出して順番に呼び出すことができます。このように、関数に名前があってもなくても、そのまま

匿名関数

を渡すこともできます。テストしてみましょう:

この実装は今のところうまく機能していますが、非同期関数の呼び出しという 1 つの状況を無視しました。非同期は JavaScript では避けられないトピックですが、ここでは JavaScript の非同期に関連するさまざまな用語や概念については説明しません (有名な解説など)。次のコードが 1、3、2 を出力することがわかっている場合は、読み続けてください:

var stack = [];
function fn1() {
  console.log('第一个调用');
}
stack.push(fn1);

function fn2() {
  console.log('第二个调用');
}
stack.push(fn2, function() { console.log('第三个调用') });

stack.forEach(function(fn) { fn() }); // 按顺序输出'第一个调用'、'第二个调用'、'第三个调用'
ログイン後にコピー

同様の非同期関数である関数がスタック キューにある場合、実装は台無しになります:

console.log(1);

setTimeout(function() {
  console.log(2);
}, 0);

console.log(3);
ログイン後にコピー

問題は明らかで、fn2 は確かに順番に呼び出されますが、setTimeout 内の関数 fn2Timeout() { console.log('2 回目の呼び出し') } はすぐには実行されません (タイムアウトが 0 に設定されている場合でも、fn2 が直後に返されます)。 fn3 が実行された後、実際に fn2Timeout の番になります。


どうやって解決しますか?ここで重要なのは fn2Timeout です。fn3 を呼び出す前に、実際に実行されるまで待つ必要があります:

var stack = [];

function fn1() { console.log('第一个调用') };
stack.push(fn1);

function fn2() {
  setTimeout(function fn2Timeout() {
     console.log('第二个调用');
  }, 0);
}
stack.push(fn2, function() { console.log('第三个调用') });

stack.forEach(function(fn) { fn() }); // 输出'第一个调用'、'第三个调用'、'第二个调用'
ログイン後にコピー

しかし、そうすることは、元の fn2Timeout を削除して新しい関数に置き換えることと同じです。をクリックし、元の fn2Timeout と fn3 を挿入します。元の機能を動的に変更するこの方法には、モンキー パッチと呼ばれる特別な用語があります。当社のプログラマーの信条によれば、「必ず実行できる」ですが、書くのは少しぎこちなく、自分自身で取り組むのは簡単です。もっと良い方法はありますか?

一歩下がって、fn3 を実行する前に fn2Timeout が完全に実行されるのを待つ必要はなく、代わりに fn2Timeout 関数本体の最後の行で呼び出します。

function fn2() {
  setTimeout(function() {
    fn2Timeout();
    fn3();
  }, 0);
}
ログイン後にコピー

これは見た目が良くなりますが、fn2 が定義されている場合、 fn3 はまだありません。fn3 はどこから来たのですか?

fn3 を fn2 で呼び出す必要があるため、stack.forEach を通じて fn3 を呼び出すことができません。そうしないと、fn3 が 2 回呼び出されることになります。

fn3 を fn2 に書き込むことはできません。代わりに、 fn2Timeout の終了時にスタック内で fn2 の次の関数を見つけて、次の関数を呼び出すだけで済みます。

function fn2() {
  setTimeout(function fn2Timeout() {
    console.log('第二个调用');
    fn3();    // 注{1}
  }, 0);
}
ログイン後にコピー

この次の関数は、スタック内の次の関数を見つけて実行する役割を果たします。次に next を実装しましょう:

function fn2() {
  setTimeout(function fn2Timeout() {
    console.log('第二个调用');
    next();
  }, 0);
}
ログイン後にコピー

next は stack[index] を使用してスタック内の関数を取得します。次の関数をフェッチする目的を達成するために、next が呼び出されるたびにインデックスが 1 ずつ増加します。

Next は次のように使用されます:

var index = 0;

function next() {
  var fn = stack[index];
  index = index + 1; // 其实也可以用shift 把fn 拿出来
  if (typeof fn === 'function') fn();
}
ログイン後にコピー

stack.forEach 行が削除されたので、Next は実行するスタック内の最初の関数 fn1 を見つけ、次の関数を見つけるために fn1 で next を呼び出します。 fn2 を実行し、fn2 で next を呼び出します。

Next はすべての関数で呼び出す必要があります。特定の関数内で記述されていない場合、プログラムは関数の実行後、続行するための機構を持たずにすぐに終了します。


この関数キューの実装を理解すると、次のインタビューの質問を解決できるはずです:

var stack = [];

// 定义index 和next

function fn1() {
  console.log('第一个调用');
  next(); // stack 中每一个函数都必须调用`next`
};
stack.push(fn1);

function fn2() {
  setTimeout(function fn2Timeout() {
     console.log('第二个调用');
     next(); // 调用`next`
  }, 0);
}
stack.push(fn2, function() {
  console.log('第三个调用');
  next(); // 最后一个可以不调用,调用也没用。
});

next(); // 调用next,最终按顺序输出'第一个调用'、'第二个调用'、'第三个调用'。
ログイン後にコピー

Node.js

これは、有名な connectframeworkミドルウェアqueue を実装する方法です。ご興味がございましたら、そのソース コードまたはこの説明「接続ミドルウェアとは」をご覧ください。
注意して見ると、この next は関数の最後にのみ配置できることがわかりますが、これが中間に配置された場合でも、元の問題が引き続き発生します:

// 实现一个LazyMan,可以按照以下方式调用:
LazyMan(“Hank”)
/* 输出: 
Hi! This is Hank!
*/

LazyMan(“Hank”).sleep(10).eat(“dinner”)输出
/* 输出: 
Hi! This is Hank!
// 等待10秒..
Wake up after 10
Eat dinner~
*/

LazyMan(“Hank”).eat(“dinner”).eat(“supper”)
/* 输出: 
Hi This is Hank!
Eat dinner~
Eat supper~
*/

LazyMan(“Hank”).sleepFirst(5).eat(“supper”)
/* 等待5秒,输出
Wake up after 5
Hi This is Hank!
Eat supper
*/

// 以此类推。
ログイン後にコピー

redux と koa は next in に配置できます。さまざまな実装による関数 途中で、次の関数を実行した後、戻って以下のコードを実行しますが、これは非常に賢い機能です。時間があるときにまた書きます。

以上がJavaScriptキュー機能とasynchronous_javascriptスキルの詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Win11での管理者権限の取得について詳しく解説 Win11での管理者権限の取得について詳しく解説 Mar 08, 2024 pm 03:06 PM

Windows オペレーティング システムは世界で最も人気のあるオペレーティング システムの 1 つであり、その新バージョン Win11 が大きな注目を集めています。 Win11 システムでは、管理者権限の取得は重要な操作であり、管理者権限を取得すると、ユーザーはシステム上でより多くの操作や設定を実行できるようになります。この記事では、Win11システムで管理者権限を取得する方法と、権限を効果的に管理する方法を詳しく紹介します。 Win11 システムでは、管理者権限はローカル管理者とドメイン管理者の 2 種類に分かれています。ローカル管理者はローカル コンピュータに対する完全な管理権限を持っています

推奨: 優れた JS オープンソースの顔検出および認識プロジェクト 推奨: 優れた JS オープンソースの顔検出および認識プロジェクト Apr 03, 2024 am 11:55 AM

顔の検出および認識テクノロジーは、すでに比較的成熟しており、広く使用されているテクノロジーです。現在、最も広く使用されているインターネット アプリケーション言語は JS ですが、Web フロントエンドでの顔検出と認識の実装には、バックエンドの顔認識と比較して利点と欠点があります。利点としては、ネットワーク インタラクションの削減とリアルタイム認識により、ユーザーの待ち時間が大幅に短縮され、ユーザー エクスペリエンスが向上することが挙げられます。欠点としては、モデル サイズによって制限されるため、精度も制限されることが挙げられます。 js を使用して Web 上に顔検出を実装するにはどうすればよいですか? Web 上で顔認識を実装するには、JavaScript、HTML、CSS、WebRTC など、関連するプログラミング言語とテクノロジに精通している必要があります。同時に、関連するコンピューター ビジョンと人工知能テクノロジーを習得する必要もあります。 Web 側の設計により、次の点に注意してください。

Oracle SQLの除算演算の詳細説明 Oracle SQLの除算演算の詳細説明 Mar 10, 2024 am 09:51 AM

OracleSQL の除算演算の詳細な説明 OracleSQL では、除算演算は一般的かつ重要な数学演算であり、2 つの数値を除算した結果を計算するために使用されます。除算はデータベース問合せでよく使用されるため、OracleSQL での除算演算とその使用法を理解することは、データベース開発者にとって重要なスキルの 1 つです。この記事では、OracleSQL の除算演算に関する関連知識を詳細に説明し、読者の参考となる具体的なコード例を示します。 1. OracleSQL での除算演算

PHPモジュロ演算子の役割と使い方を詳しく解説 PHPモジュロ演算子の役割と使い方を詳しく解説 Mar 19, 2024 pm 04:33 PM

PHP のモジュロ演算子 (%) は、2 つの数値を除算した余りを取得するために使用されます。この記事では、モジュロ演算子の役割と使用法について詳しく説明し、読者の理解を深めるために具体的なコード例を示します。 1. モジュロ演算子の役割 数学では、整数を別の整数で割ると、商と余りが得られます。たとえば、10 を 3 で割ると、商は 3 になり、余りは 1 になります。モジュロ演算子は、この剰余を取得するために使用されます。 2. モジュロ演算子の使用法 PHP では、% 記号を使用してモジュロを表します。

Linuxシステムコールsystem()関数の詳細説明 Linuxシステムコールsystem()関数の詳細説明 Feb 22, 2024 pm 08:21 PM

Linux システム コール system() 関数の詳細説明 システム コールは、Linux オペレーティング システムの非常に重要な部分であり、システム カーネルと対話する方法を提供します。その中でも、system()関数はよく使われるシステムコール関数の一つです。この記事では、system() 関数の使用法を詳しく紹介し、対応するコード例を示します。システム コールの基本概念 システム コールは、ユーザー プログラムがオペレーティング システム カーネルと対話する方法です。ユーザープログラムはシステムコール関数を呼び出してオペレーティングシステムを要求します。

Linuxのcurlコマンドの詳しい説明 Linuxのcurlコマンドの詳しい説明 Feb 21, 2024 pm 10:33 PM

Linuxのcurlコマンドの詳細な説明 要約:curlは、サーバーとのデータ通信に使用される強力なコマンドラインツールです。この記事では、curl コマンドの基本的な使用法を紹介し、読者がコマンドをよりよく理解して適用できるように実際のコード例を示します。 1.カールとは何ですか? curl は、さまざまなネットワーク要求を送受信するために使用されるコマンド ライン ツールです。 HTTP、FTP、TELNETなどの複数のプロトコルをサポートし、ファイルアップロード、ファイルダウンロード、データ送信、プロキシなどの豊富な機能を提供します。

jsとvueの関係 jsとvueの関係 Mar 11, 2024 pm 05:21 PM

js と vue の関係: 1. Web 開発の基礎としての JS、2. フロントエンド フレームワークとしての Vue.js の台頭、3. JS と Vue の補完関係、4. JS と Vue の実用化ビュー。

Promise.resolve() について詳しく見る Promise.resolve() について詳しく見る Feb 18, 2024 pm 07:13 PM

Promise.resolve() の詳細な説明には、特定のコード例が必要です。Promise は、非同期操作を処理するための JavaScript のメカニズムです。実際の開発では、順番に実行する必要があるいくつかの非同期タスクを処理する必要があることがよくあり、満たされた Promise オブジェクトを返すために Promise.resolve() メソッドが使用されます。 Promise.resolve() は Promise クラスの静的メソッドであり、

See all articles