🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

Q&A

解決済

1回答

3797閲覧

Ajaxがタイムアウトした場合、その次の処理がわからない

massuguda

総合スコア23

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

0グッド

0クリップ

投稿2021/02/09 09:21

編集2021/02/09 09:49

以下リンクを読み、Ajaxにタイムアウトを追加しました。

非同期通信(Ajax)をするときはタイムアウト処理を必ず入れてほしい(切実)
https://qiita.com/tonkotsuboy_com/items/d1b3cf45ae5135441f9b

しかし次の不整合で悩んでいます。

###フロントエンドとバックエンドの不整合
タイムアウトしたからといって、バックエンド(PHPとSQL)はDBにレコードINSERTを続けますし、それが成功すれば普通にフォロー情報はINSERT済となります。

しかしフロントエンドではalert('タイムアウトしました')のようなエラーを出して、<button>フォロー済</button><button>未フォロー</button>へと戻します。

つまりこの時点で、
・フロントエンドの「未フォロー」
・バックエンドの「フォロー情報INSERT済」
という不整合が生じると思います。

###質問事項

タイムアウトしたら、上記不整合をどうやって調整するのでしょうか?

まさかもう一度Ajaxを流して、「さっきのフォロー情報のレコードをDELETEせよ」とするのでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2021/02/09 09:48

INSETとかDELATEとか気にされたほうが良いと思います。 書いたとおりにしかプログラムは動きませんし、文章中とはいえ、雑にやってしまうとコードに表れます。
massuguda

2021/02/09 09:50

おおっと、大変失礼致しました。
m.ts10806

2021/02/09 09:50 編集

あと、実際に不整合がでるかどうか検証されたほうが良いかもしれません。
hentaiman

2021/02/09 10:07

成功を前提に作ったプログラムは危険ですぞ。 テスト仕様書を作って細かくテストすれば自ずと対策も湧きそうなものですが。
guest

回答1

0

ベストアンサー

クライアント側の見切りのtimeoutなのか、サーバー側のシステム的なtimeoutなのかによって違います。
たとえばjsで10秒でabortする仕組みにすると、なにも伝えなければサーバー側は
timeout後もせっせと処理をつづけます。
その場合api.php?timeout=10のように何秒間頑張れという指示をだしておきます

投稿2021/02/10 01:15

yambejp

総合スコア116690

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yambejp

2021/02/10 01:16

あとはこんな感じ $timeout=filter_input(INPUT_GET,'timeout',FILTER_VALIDATE_FLOAT)?:0; $start = microtime(true); $dsn = 'mysql:host=localhost; dbname=hoge;charset=utf8;'; $user = 'root'; $password = 'root'; $pdo = new PDO($dsn, $user,$password); $pdo->beginTransaction(); $sql="INSERT INTO ・・・"; $stmt = $pdo->query($sql); $end = microtime(true); if($end-$start<$timeout){ $pdo->commit(); }
yambejp

2021/02/10 01:17

ちゃんとやるならrollbackも明確に指示したほうがよいでしょう
massuguda

2021/02/10 02:30

ありがとうございます。タイムアウト情報は、質問の $.ajax({ type:"GET", url:hogeURL, cache: false, timeout: 10000, }).then( successHandler, errorHandler ); だけでなく $.ajax({ type:"GET", url:hogeURL, // パラメータに '?timeout=10' を追加 cache: false, timeout: 10000, data: {timeout:10000} }).then( successHandler, errorHandler ); としたり $.ajax({ type:"GET", url:hogeURL, cache: false, timeout: 10000, data:{timeout:10} // POSTに追加 }).then( successHandler, errorHandler ); としたりでタイムアウトを送るわけですね。 そしてそれを受け取ったPHPでは $pdo->query($sql);の前後でmicrotimeで時間を測ると。 なるほどです。イメージできました。 rollback含めアドバイスありがとうございました。実装してみたいと思います。
massuguda

2021/02/10 02:34

すると「PHPのmicrotime」は「JSから送るtimeout」と微妙に異なる(PHPの方が計測開始がやや遅くなる)わけですから、JSが質問のように100000ならば、microtimeは if($end-$start<$timeout) よりも微妙に(例えば1秒くらい)短くして if($end-$start<($timeout-100000)) にした方がいい、とかあるでしょうか?
yambejp

2021/02/10 03:00

注意:PHP側の$timeoutは秒単位の想定です PHPについては$timeoutによって完了するかどうかなので こまかい調整はさほど必要ではないような気がします。 当然ですがinsert処理がtimeoutして完了しないということは その後再処理をしてもいつまでたってもデータ投入ができないということです insertの処理について見直しが必要です
massuguda

2021/02/12 05:31

遅くなり申し訳ございません。 注意の方ですが、$end = microtime(true);としていらっしゃいますから、秒でなくマイクロ秒ではないでしょうか?つまり先の返信のように、JSが質問のように100000ならば、if($end-$start<($timeout-100000)) では?と思うのですが、違いますか? insert失敗の方ですが、データは投入せず、フロントで「投入できませんでした。あとでもう一回試してください」と表示するつもりですが、こういう処理であっていますよね?(普通こういう処理ですよね?)
yambejp

2021/02/12 05:40

マイクロ秒同士の引き算は秒で返ってくるという意味です $start=microtime(true); sleep(2); $end=microtime(true); print $end-$start;
massuguda

2021/02/12 07:50

なるほど!どうもありがとうございます。大変勉強になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問