ホームページ ウェブフロントエンド jsチュートリアル JSキュー関数の詳細説明と非同期実行例

JSキュー関数の詳細説明と非同期実行例

Jul 07, 2017 pm 02:57 PM
javascript 埋め込む

この記事では主に 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 に配置できます。さまざまな実装による関数 途中で、次の関数を実行した後、戻って以下のコードを実行しますが、これは非常に賢い機能です。時間があるときにまた書きます。

以上がJSキュー関数の詳細説明と非同期実行例の詳細内容です。詳細については、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)

WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 Dec 17, 2023 pm 02:54 PM

WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 はじめに: 技術の継続的な発展により、音声認識技術は人工知能の分野の重要な部分になりました。 WebSocket と JavaScript をベースとしたオンライン音声認識システムは、低遅延、リアルタイム、クロスプラットフォームという特徴があり、広く使用されるソリューションとなっています。この記事では、WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法を紹介します。

WebSocket と JavaScript: リアルタイム監視システムを実装するための主要テクノロジー WebSocket と JavaScript: リアルタイム監視システムを実装するための主要テクノロジー Dec 17, 2023 pm 05:30 PM

WebSocketとJavaScript:リアルタイム監視システムを実現するためのキーテクノロジー はじめに: インターネット技術の急速な発展に伴い、リアルタイム監視システムは様々な分野で広く利用されています。リアルタイム監視を実現するための重要なテクノロジーの 1 つは、WebSocket と JavaScript の組み合わせです。この記事では、リアルタイム監視システムにおける WebSocket と JavaScript のアプリケーションを紹介し、コード例を示し、その実装原理を詳しく説明します。 1.WebSocketテクノロジー

Go 言語のインデントの仕様と例 Go 言語のインデントの仕様と例 Mar 22, 2024 pm 09:33 PM

Go 言語のインデント仕様と例 Go 言語は Google によって開発されたプログラミング言語であり、その簡潔で明確な構文で知られており、インデント仕様はコードの読みやすさと美しさに重要な役割を果たします。この記事ではGo言語のインデントの仕様を紹介し、具体的なコード例を通して詳しく解説します。インデントの仕様 Go 言語では、スペースの代わりにタブがインデントに使用されます。インデントの各レベルは 1 つのタブで、通常はスペース 4 個の幅に設定されます。このような仕様により、コーディング スタイルが統一され、チームが協力してコンパイルできるようになります。

JavaScript と WebSocket を使用してリアルタイムのオンライン注文システムを実装する方法 JavaScript と WebSocket を使用してリアルタイムのオンライン注文システムを実装する方法 Dec 17, 2023 pm 12:09 PM

JavaScript と WebSocket を使用してリアルタイム オンライン注文システムを実装する方法の紹介: インターネットの普及とテクノロジーの進歩に伴い、ますます多くのレストランがオンライン注文サービスを提供し始めています。リアルタイムのオンライン注文システムを実装するには、JavaScript と WebSocket テクノロジを使用できます。 WebSocket は、TCP プロトコルをベースとした全二重通信プロトコルで、クライアントとサーバー間のリアルタイム双方向通信を実現します。リアルタイムオンラインオーダーシステムにおいて、ユーザーが料理を選択して注文するとき

Oracle DECODE関数の詳細説明と使用例 Oracle DECODE関数の詳細説明と使用例 Mar 08, 2024 pm 03:51 PM

Oracle の DECODE 関数は、クエリ ステートメントのさまざまな条件に基づいてさまざまな結果を返すためによく使用される条件式です。この記事ではDECODE関数の構文・使い方・サンプルコードを詳しく紹介します。 1. DECODE 関数の構文 DECODE(expr,search1,result1[,search2,result2,...,default]) expr: 比較する式またはフィールド。検索1、

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 Dec 17, 2023 pm 05:13 PM

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 はじめに: 今日、天気予報の精度は日常生活と意思決定にとって非常に重要です。テクノロジーの発展に伴い、リアルタイムで気象データを取得することで、より正確で信頼性の高い天気予報を提供できるようになりました。この記事では、JavaScript と WebSocket テクノロジを使用して効率的なリアルタイム天気予報システムを構築する方法を学びます。この記事では、具体的なコード例を通じて実装プロセスを説明します。私たちは

簡単な JavaScript チュートリアル: HTTP ステータス コードを取得する方法 簡単な JavaScript チュートリアル: HTTP ステータス コードを取得する方法 Jan 05, 2024 pm 06:08 PM

JavaScript チュートリアル: HTTP ステータス コードを取得する方法、特定のコード例が必要です 序文: Web 開発では、サーバーとのデータ対話が頻繁に発生します。サーバーと通信するとき、多くの場合、返された HTTP ステータス コードを取得して操作が成功したかどうかを判断し、さまざまなステータス コードに基づいて対応する処理を実行する必要があります。この記事では、JavaScript を使用して HTTP ステータス コードを取得する方法を説明し、いくつかの実用的なコード例を示します。 XMLHttpRequestの使用

ブラウザで PHP コードを記述し、コードが実行されないようにするにはどうすればよいでしょうか? ブラウザで PHP コードを記述し、コードが実行されないようにするにはどうすればよいでしょうか? Mar 10, 2024 pm 02:27 PM

ブラウザで PHP コードを記述し、コードが実行されないようにするにはどうすればよいでしょうか?インターネットの普及に伴い、Web開発に触れる人が増え、PHPの学習にも注目が集まっています。 PHP はサーバー側で実行されるスクリプト言語であり、動的な Web ページを作成するためによく使用されます。ただし、演​​習フェーズでは、ブラウザーで PHP コードを作成して結果を確認できるようにしたいと考えていますが、コードが実行されることは望ましくありません。では、ブラウザで PHP コードを記述し、それが実行されないようにするにはどうすればよいでしょうか?以下、詳細に説明する。初め、

See all articles