先日、iPhoneのショートカットアプリの“WebページでJavaScriptを実行”というアクションでalert()
を使ったところ「JavaScriptタイムアウト」というエラーが出ました。
どうやらSafariのJavaScriptには制限時間があり、これを超えるとタイムアウトのエラーが出てしまうようです。
また、普段問題なく使えているショートカットでも時折同じエラーが出ることがあるようなので、この時の対処方法もご紹介します。
公式サイトも参考に、JavaScriptタイムアウトの対処方法を纏めました。
この記事の目次
ショートカットアプリでJavaScriptタイムアウトが出る時の対処方法
この度、iPhoneやiPadに初めから入っているiOSのショートカットアプリ(↓)で「JavaScriptタイムアウト」というエラーが出ました。
今回ショートカットで使える、“WebページでJavaScriptを実行”というアクションを使ってJavaScriptでWebページ上の全てのリンク(a要素)を抜き出した後、alert()
メソッドで取得した要素を表示しようとした時にタイムアウトのエラーが出ました。
エラーが出た時の様子が以下です。
GIFなので少しし分かりにくいですが、こんな感じです。
実際にはショートカットを押した後、約2秒ほど経った後にJavaScriptタイムアウトというエラーが表示される感じです。
エラーの全文が見えないのでスマホを横向きにして実行してみます。
WebページでJavaScriptを実行
JavaScriptタイムアウト
completionハンドラの呼び出しに時間がかかりすぎたため、"WebページでJavaScriptを実行"ができませんでした。
とあります...。ナニコレ!?初めて見るエラーです。
一応タイムアウトのエラーが発生するまでに意図した処理は完了している様子...。
しかし、毎回このエラーが出るのもアレなので原因と対象方法を調べました。
JavaScriptタイムアウトの原因は処理時間
エラーの内容がタイムアウトなので、所定の時間までに今回作成したショートカットの処理が完了しなかったことがエラーの原因と考えられます。
調べてみるとAppleの公式サイトに詳しい説明がありました。
公式サイトには「JavaScriptタイムアウト」の説明として以下のようにあります。
「WebページでJavaScriptを実行」アクションは、SafariのすべてのJavaScript機能拡張と同様に時間制限が適用されるため、できるだけ素早く完了する必要があります。同期関数を使用する以下のようなJavaScriptは、時間内に完了しない場合があります:
- window.alert()
- window.prompt()
- window.confirm()
- 2秒以上のタイムアウト。例: window.setTimeout(function() { completion(); }, 5000);
JavaScriptが時間制限を超えると、ショートカットを実行しても完了せず、「JavaScriptタイムアウト」エラーメッセージが表示されます。
ここで、説明にある各関数の動作は以下のような感じです。
alert() | メッセージを画面上にポップアップ表示するメソッド。 |
prompt() | 任意のメッセージと入力ダイアログを表示するメソッド。 |
confirm() | 任意のメッセージと確認ダイアログを表示するメソッド。 |
setTimeout() | 指定した時間後に関数を呼び出すタイマーのようなもの。 |
上記が同期関数の例として挙げられていました。
同期処理はその処理が終わるまで他の処理を中断する感じですが、その処理に時間がかかりすぎるとJavaScriptタイムアウトというエラーが出てしまうようですね。
そして最後にある「2秒以上のタイムアウト」という例から、恐らくタイムアウトが発生する条件は処理に2秒以上かかった場合なのかと推測できます。
実際にショートカットを押してから2秒ほど経った後にタイムアウトのエラーが表示されますので、多分そういう事なのでしょう。つまり完了ハンドラcompletion();に2秒未満で辿り着かないとダメという事っぽいです。
コールバック等で回避できるかは今まだ未確認です。時間があればやってみます。
今まで使っていたショートカットでJavaScriptタイムアウトが出た時の対処方法
続いて今まで問題なく使えていたショートカットに突然「JavaScriptタイムアウト」のエラーが発生した時の対処方法です。
実はJavaScriptタイムアウトが初めて出た時に色々試していたのですが、ついには今まで問題なく使っていた「Safariスーパーリロード」という既存のショートカットでも同じエラーが発生してしまいました。
このショートカット、コードの中身は以下のようなものです。
completion(window.location.reload(true));
ページをスーパーリロードするだけのものなので処理には2秒もかかりません。
にもかかわらず、今回JavaScriptタイムアウトが出るようになってしまいました。
で色々試した結果、既存のショートカットにタイムアウトが出た時は端末(iPhone)を再起動すれば治るという事が判明しました。
これは原因が良く分からないのですが、ショートカットアプリにもキャッシュのようなゴミが溜まって処理が重たくなってしまうのでは?と推測しています。
ショートカットの調子が悪い時は端末の再起動。これにつきます。
まとめ
以上「ショートカット」アプリでJavaScriptタイムアウトが出る時の確認でした。
まぁなんとも歯切れの悪い記事になってしまいました。
時間があればもっとテストしてみて、2秒以上かかる処理でもタイムアウトが出ないような方法を検証したいと思っていますがまだやっていません。
完成度の低い記事ですが、何かの参考になれば幸いです。