ECMAScript の Promise ES2015 と async/await ES2017 機能がリリースされて以来、非同期はフロントエンドの世界で特に一般的な操作になりました。非同期コードと同期コードが問題を処理する順序には若干の違いがあります。非同期コードを書くには、同期コードを書く場合とは異なる「意識」が必要です。 コードの実行に長い時間がかかる場合はどうなりますか?これが同期コードの場合、「無応答」、または平易な言葉で言えば「死」と呼ばれる現象が発生しますが、非同期コードの場合はどうなるでしょうか。結果は得られないかもしれませんが、他のコードは何も起こらなかったかのように続行されます。 もちろん、実際に何も起こらなかったわけではなく、状況が異なれば異なる現象が起こるというだけです。たとえば、読み込みアニメーションのあるページは常に読み込み中のように見えます。別の例としては、データが更新されるはずなのにデータの変更が見えないページがあります。 例えば、どうやってもダイアログボックスを閉じることができない…このような現象をバグと呼びます。しかし、非同期操作プロセスが「エコー」せず、そこで静かに終了する場合もあります。誰もそれを知ることはなく、ページが更新された後は痕跡さえ残りません。 Axiosにはタイムアウト処理機能が搭載されているAxios を使用して Web API 呼び出しを行うことは、一般的な非同期操作プロセスです。通常、コードは次のように記述されます。 試す { const res = axios.get(url, options); を待機します。 //TODO 後続の業務を通常どおり続行します} catch(err) { // TODO フォールトトレランスを実行するかエラーを報告する} このコードは通常はうまく機能しますが、ある日ユーザーから「なぜこんなに長く待っても応答がないのか」という苦情が寄せられます。 その後、開発者は、サーバーへの負荷が増大したため、この要求に即座に応答することが困難であることに気付きました。ユーザーの気持ちを考慮して、読み込みアニメーションが追加されます。 試す { 読み込み中を表示します。 const res = axios.get(url, options); を待機します。 //TODO 通常業務} catch (err) { //TODO フォールトトレランス処理} finally { 読み込みを非表示にします(); } しかし、ある日、あるユーザーが「30 分待ったが、ぐるぐる回り続けるだけだ!」と言いました。そこで開発者は、何らかの理由でリクエストが停止していることに気付きました。この場合、リクエストを再送信するか、ユーザーに直接報告する必要があります。つまり、タイムアウト チェックを追加する必要があります。 幸いなことに、Axios はタイムアウトを処理できます。 試す {...} キャッチ(エラー){ if (err.isAxiosError && !err.response && err.request && err.message.startsWith("タイムアウト")) { // Axios リクエストが間違っていて、メッセージが遅延メッセージである場合 // TODO はタイムアウトを処理します} } ついに {...} Axios は問題ありませんが、 fetch() タイムアウトの処理
const ac = 新しい AbortController(); const {シグナル} = ac; fetch(url, { signal }).then(res => { //TODO ビジネスを処理する}); // 1 秒後にフェッチ操作をキャンセルします setTimeout(() => ac.abort(), 1000); 上記の例は const ac = 新しい AbortController(); const {シグナル} = ac; タイムアウトを設定します(() => ac.abort(), 1000); const res = await fetch(url, { signal }).catch(() => undefined); リクエストの失敗を処理するために ここで終了することもできましたが、各 非同期関数 fetchWithTimeout(timeout, resoure, init = {}) { const ac = 新しい AbortController(); 定数シグナル = ac.signal; setTimeout(() => ac.abort(), タイムアウト); return fetch(リソース、{...init、signal}); } それでいいですか?いいえ、問題があります。 上記のコードの タイムアウトを設定する(() => { console.log("タイムアウトです"); ac.abort(); }、 タイムアウト); そして、電話には十分な時間をかけましょう。 fetchWithTimeout(5000, url).then(res => console.log("success")); 出力 ちなみに、 非同期関数 fetchWithTimeout(timeout, resoure, init = {}) { const ac = 新しい AbortController(); 定数シグナル = ac.signal; 定数タイマー = setTimeout(() => { console.log("タイムアウトです"); ac.abort() を返します。 }、 タイムアウト); 試す { return await fetch(resoure, { ...init, signal }); ついに タイマーをクリアします。 } } 完璧!しかし、問題はまだ終わっていません。 すべてがタイムアウトになる可能性があるAxios と fetch はどちらも非同期操作を中断する方法を提供していますが、 そのような約束に対して、私が言えるのは、彼を行かせなさい、彼が永遠にそれを続けさせなさいということだけです。どうせ私は彼を止めることはできません。でも人生は続いていくので、待ち続けることはできません! この場合、 Race はレースを意味するので、 関数 waitWithTimeout(promise, timeout, timeoutMessage = "timeout") { タイマーを設定します。 const timeoutPromise = 新しい Promise((_, 拒否) => { タイマー = setTimeout(() => 拒否(timeoutMessage)、タイムアウト); }); Promise.race([timeoutPromise, promise]) を返します。 .finally(() => clearTimeout(timer)); // タイマーをクリアするのを忘れないでください } 効果をシミュレートするために Timeout を記述できます。 (非同期() => { const business = new Promise(resolve => setTimeout(resolve, 1000 * 10)); 試す { waitWithTimeout(ビジネス、1000) を待機します。 console.log("[成功]"); } キャッチ (エラー) { console.log("[エラー]", err); // [エラー] タイムアウト } })(); 上記は、JavaScript フロントエンドのタイムアウト非同期操作に対する完璧なソリューションの詳細な内容です。フロントエンドのタイムアウト非同期操作の解決の詳細については、123WORDPRESS.COM の他の関連記事に注目してください。 以下もご興味があるかもしれません:
|
>>: CSS で中空マスク レイヤーを実装するサンプル コード
目次導入実装手順キャンバス環境を作成するライティングボールBallクラスを継承するMoveBallク...
1. ツール今必要なツールは2つあります: MySQLサーバー (mysql-5.7.18)、MyS...
先日、外国人の方がHTML+CSSを使ってHamburgerMenuを実装している動画を見ました。最...
序文最近 Linux を学び、その後 Win から Ubuntu に変更しました。以前インストールし...
実際の開発ではポップアップウィンドウがよく使われます。CSS3を勉強していたときに、閉じることができ...
序文データベース操作では、同時データ読み取りの正確性を効果的に保証するために、トランザクション分離レ...
ツリーマップは主にツリーのようなデータ構造を視覚化するために使用され、特殊なタイプの階層です。これを...
目次1. いくつか2. すべての3. 見つける1. いくつかsome()メソッドは、指定された関数の...
JDBCデータベースリンクと関連メソッドのカプセル化の詳細な説明MySQL データベースを使用して、...
HTML画像にハイパーリンクを追加すると醜い青い枠線が表示される次のように:解決: CSS スタイル...
最近、UTF8 エンコードの中国語 Zen Cart Web サイトをデバッグしているときに奇妙な現...
この記事では、vueの大画面表示適応の具体的なコードを参考までに紹介します。具体的な内容は以下のとお...
目次序文1. スケーラビリティとは何ですか?スケールアウトの利点:スケールアウトのデメリット:スケー...
ステップ1: MySQL YUMソースを取得するMySQLの公式サイトにアクセスして、RPMパッケー...
MySQL 8.0.13 にはデフォルトでデータ フォルダがあります。このフォルダを削除する必要があ...