JavaScript での正しいエラー処理の概要
この記事では、クライアントサイド JavaScript でのエラー処理について説明します。主にJavaScriptでよくある間違いやエラー処理、非同期コードの書き方などを紹介します。 JavaScript でエラーを正しく処理する方法を見てみましょう
JavaScript のイベント駆動型パラダイムにより、リッチな言語が追加され、JavaScript でのプログラミングがより多様になります。ブラウザを JavaScript のイベント駆動型ツールと考えると、エラーが発生するとイベントがスローされます。理論的には、これらのエラーは JavaScript の単純なイベントであると考えることができます。
この記事では、クライアントサイド JavaScript でのエラー処理について説明します。主にJavaScriptでよくある間違いやエラー処理、非同期コードの書き方などを紹介します。
JavaScript でエラーを正しく処理する方法を見てみましょう。
デモ
この記事で使用されているデモは、GitHub にあります。実行後、ページは次のようになります:
各ボタンは「エラー (例外)」をトリガーします。 error スローされた例外 TypeError をシミュレートします。モジュール定義は次のとおりです:
// scripts/error.js function error() { var foo = {}; return foo.bar(); }
まず、この関数は空のオブジェクト foo を宣言します。 bar() はどこにも定義されていないことに注意してください。次に、この単体テストが「エラー」をスローするかどうかを確認します。
// tests/scripts/errorTest.js it('throws a TypeError', function () { should.throws(error, TypeError); });
この単体テストは Mocha にあり、Should.js にテスト宣言があります。 Mocha はテスト ランナー ツールで、Should.js はアサーション ライブラリです。この単体テストはノード上で実行され、ブラウザを使用する必要はありません。
error() は空のオブジェクトを定義し、メソッドにアクセスしようとします。 bar() がオブジェクト内に存在しないため、例外がスローされます。 JavaScript のような動的言語で発生するこのエラーは、誰にでも起こる可能性があります。
エラー処理 (1)
上記のエラーを処理するには、次のコードを使用します:
// scripts/badHandler.js function badHandler(fn) { try { return fn(); } catch (e) { } return null; }
ハンドラーは fn を入力パラメーターとして受け取り、ハンドラー関数内で fn が呼び出されます。単体テストには、上記のエラー ハンドラーの役割が反映されます:
// tests/scripts/badHandlerTest.js it('returns a value without errors', function() { var fn = function() { return 1; }; var result = badHandler(fn); result.should.equal(1); }); it('returns a null with errors', function() { var fn = function() { throw new Error('random error'); }; var result = badHandler(fn); should(result).equal(null); });
何か問題が発生した場合、エラー ハンドラーは null を返します。 fn() コールバック関数は、正当なメソッドまたはエラーを指すことができます。
次のクリック イベントはイベント処理を続行します:
// scripts/badHandlerDom.js (function (handler, bomb) { var badButton = document.getElementById('bad'); if (badButton) { badButton.addEventListener('click', function () { handler(bomb); console.log('Imagine, getting promoted for hiding mistakes'); }); } }(badHandler, error));
この処理方法はコード内のエラーを隠すため、見つけるのが困難です。隠れたエラーのデバッグには何時間もかかる場合があります。特にコールスタックが深いマルチレイヤーソリューションでは、このエラーを見つけるのが難しくなる可能性があります。したがって、これはエラーを処理する非常に不適切な方法です。
エラー処理(2)
もう一つのエラー処理方法は以下の通りです。
// scripts/uglyHandler.js function uglyHandler(fn) { try { return fn(); } catch (e) { throw new Error('a new error'); } }
例外が処理される方法は次のとおりです:
// tests/scripts/uglyHandlerTest.js it('returns a new error with errors', function () { var fn = function () { throw new TypeError('type error'); }; should.throws(function () { uglyHandler(fn); }, Error); });
上記は、エラー ハンドラーの大幅な改善です。ここで、例外により呼び出しスタックがバブルアップされます。同時に、エラーによってスタックが拡張されるため、デバッグに非常に役立ちます。例外をスローすることに加えて、インタプリタはスタックに沿って追加の処理を探します。これにより、スタックの最上位からエラーが処理される可能性も生じます。しかし、これは依然として不十分なエラー処理であり、元の例外をスタックの下に段階的に追跡する必要があります。
カスタム エラー メソッドを使用して、この不適切なエラー処理を終了する代替手段を採用できます。このアプローチは、エラーに詳細を追加するときに役立ちます。
例:
// scripts/specifiedError.js // Create a custom error var SpecifiedError = function SpecifiedError(message) { this.name = 'SpecifiedError'; this.message = message || ''; this.stack = (new Error()).stack; }; SpecifiedError.prototype = new Error(); SpecifiedError.prototype.constructor = SpecifiedError; // scripts/uglyHandlerImproved.js function uglyHandlerImproved(fn) { try { return fn(); } catch (e) { throw new SpecifiedError(e.message); } } // tests/scripts/uglyHandlerImprovedTest.js it('returns a specified error with errors', function () { var fn = function () { throw new TypeError('type error'); }; should.throws(function () { uglyHandlerImproved(fn); }, SpecifiedError); });
指定されたエラーにより詳細が追加され、元のエラー メッセージが保持されます。この改良により、上記の処理は下手な処理方法ではなく、明確で有用な処理方法となりました。
上記の処理後、ハンドルされない例外も受け取りました。次に、エラー処理時にブラウザがどのように役立つかを見てみましょう。
スタックを拡張する
例外を処理する 1 つの方法は、呼び出しスタックの先頭に try...catch を追加することです。
例:
function main(bomb) { try { bomb(); } catch (e) { // Handle all the error things } }
ただし、ブラウザはイベント駆動型であり、JavaScript の例外もイベントです。例外が発生すると、インタープリターは実行を一時停止して巻き戻します。
// scripts/errorHandlerDom.js window.addEventListener('error', function (e) { var error = e.error; console.log(error); });
このイベント ハンドラーは、実行コンテキストで発生するエラーをキャッチします。さまざまなターゲットで発生するエラー イベントは、さまざまなタイプのエラーを引き起こす可能性があります。コード内でのこの集中エラー処理は非常に積極的です。デイジーチェーンを使用して特定のエラーを処理できます。 SOLID 原則に従えば、単一の目的でエラー処理を使用できます。これらのハンドラーはいつでも登録でき、インタープリターは実行する必要のあるハンドラーをループします。コード ベースは try...catch ブロックから解放できるため、デバッグも簡単になります。 JavaScript では、エラー処理をイベント処理として扱うことが重要です。
捕获堆栈
在解决问题时,调用堆栈会非常有用,同时浏览器正好可以提供这些信息。虽然堆栈属性不是标准的一部分,但是最新的浏览器已经可以查看这些信息了。
下面是在服务器上记录错误的示例:
// scripts/errorAjaxHandlerDom.js window.addEventListener('error', function (e) { var stack = e.error.stack; var message = e.error.toString(); if (stack) { message += '\n' + stack; } var xhr = new XMLHttpRequest(); xhr.open('POST', '/log', true); // Fire an Ajax request with error details xhr.send(message); });
每个错误处理都具有单个目的,这样可以保持代码的DRY原则(目的单一,不要重复自己原则)。
在浏览器中,需要将事件处理添加到DOM。这意味着如果你正在构建第三方库,那么你的事件会与客户端代码共存。window.addEventListener( )会帮你进行处理,同时也不会抹去现有的事件。
这是服务器上日志的截图:
可以通过命令提示符查看日志,但是Windows上,日志是非动态的。
通过日志可以清楚的看到,具体什么情况触发了什么错误。在调试时调用堆栈也会非常有用,所以不要低估调用堆栈的作用。
在JavaScript中,错误信息仅适用于单个域。因为在使用来自不用域的脚本时,将会看不到任何错误详细信息。
一种解决方案是重新抛出错误,同时保留错误消息:
一旦重新启动了错误备
try { return fn(); } catch (e) { throw new Error(e.message); }
份,全局错误处理程序就会完成其余的工作。确保你的错误处理处在相同域中,这样会保留原始消息,堆栈和自定义错误对象。
异步处理
JavaScript在运行异步代码时,进行下面的异常处理,会产生一个问题:
// scripts/asyncHandler.js function asyncHandler(fn) { try { // This rips the potential bomb from the current context setTimeout(function () { fn(); }, 1); } catch (e) { } }
通过单元测试来查看问题:
// tests/scripts/asyncHandlerTest.js it('does not catch exceptions with errors', function () { // The bomb var fn = function () { throw new TypeError('type error'); }; // Check that the exception is not caught should.doesNotThrow(function () { asyncHandler(fn); }); });
这个异常没有被捕获,我们通过单元测试来验证。尽管代码包含了try...catch,但是try...catch语句只能在单个执行上下文中工作。当异常被抛出时,解释器已经脱离了try...catch,所以异常未被处理。Ajax调用也会发生同样的情况。
所以,一种解决方案是在异步回调中捕获异常:
setTimeout(function () { try { fn(); } catch (e) { // Handle this async error } }, 1);
这种做法会比较奏效,但仍有很大的改进空间。
首先,这些try...catch block在整个区域纠缠不清。事实上,V8浏览器引擎不鼓励在函数内使用try ... catch block。V8是Chrome浏览器和Node中使用的JavaScript引擎。一种做法是将try...catch block移动到调用堆栈的顶部,但这却不适用于异步代码编程。
由于全局错误处理可以在任何上下文中执行,所以如果为错误处理添加一个窗口对象,那么就能保证代码的DRY和SOLID原则。同时全局错误处理也能保证你的异步代码很干净。
以下是该异常处理在服务器上的报告内容。请注意,输出内容会根据浏览器的不同而不同。
从错误处理中可以看到,错误来自于异步代码的setTimeout( )功能。
结论
在进行错误处理时,不要隐藏问题,而应该及时发现问题,并采用各种方法追溯问题的根源以便解决问题。虽然编写代码时,时常难免会埋下错误,但是我们也无须为错误的发生过于感到羞愧,及时解决发现问题从而避免更大的问题发生,正是我们现在需要做的。
总结
以上がJavaScript での正しいエラー処理の概要の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

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

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

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

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

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

ホットトピック









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

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

株式分析に必須のツール: PHP および JS でローソク足チャートを描画する手順を学びます。特定のコード例が必要です。インターネットとテクノロジーの急速な発展に伴い、株式取引は多くの投資家にとって重要な方法の 1 つになりました。株価分析は投資家の意思決定の重要な部分であり、ローソク足チャートはテクニカル分析で広く使用されています。 PHP と JS を使用してローソク足チャートを描画する方法を学ぶと、投資家がより適切な意思決定を行うのに役立つ、より直感的な情報が得られます。ローソク足チャートとは、株価をローソク足の形で表示するテクニカルチャートです。株価を示しています

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

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

WebSocket と JavaScript を使用してオンライン予約システムを実装する方法 今日のデジタル時代では、ますます多くの企業やサービスがオンライン予約機能を提供する必要があります。効率的かつリアルタイムのオンライン予約システムを実装することが重要です。この記事では、WebSocket と JavaScript を使用してオンライン予約システムを実装する方法と、具体的なコード例を紹介します。 1. WebSocket とは何ですか? WebSocket は、単一の TCP 接続における全二重方式です。

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

インターネット金融の急速な発展に伴い、株式投資を選択する人がますます増えています。株式取引では、ローソク足チャートは一般的に使用されるテクニカル分析手法であり、株価の変化傾向を示し、投資家がより正確な意思決定を行うのに役立ちます。この記事では、PHP と JS の開発スキルを紹介し、株価ローソク足チャートの描画方法を読者に理解してもらい、具体的なコード例を示します。 1. 株のローソク足チャートを理解する 株のローソク足チャートの描き方を紹介する前に、まずローソク足チャートとは何かを理解する必要があります。ローソク足チャートは日本人が開発した
