JavaScript内に待機時間を設定
この記事では、JavaScriptメソッドのsetTimeoutをAUTOROで活用する方法を紹介します。setTimeoutメソッドではJavaScriptコードの実行途中に待機時間を設けることができます。
【できるようになること】
- setTimeoutの使い方
- setTimeoutを活用
InjectScriptでsetTimeout()やasync/awaitを利用すると、以下のようなことが可能になります。
- InjectScriptの実行終了後もJavaScriptが実行され続ける状況を作る
- InjectScriptのスクリプト内部に待機時間を設ける
setTimeoutとは
setTimeoutメソッドを利用すると、JavaScriptの実行の途中に待機時間を設定することができます。
構文:setTimeout(functionName, delayTime, value1, value2...)
- 第1引数:実行するfunction関数(必須)
- 第2引数:待機時間(ミリ秒/任意)
- 第3引数以降:実行するfunctionの引数に渡す値(任意)
[参考文献]
ワークフローと平行して、バックグラウンドでJavaScriptを実行し続ける
InjectScriptでsetTimeoutを利用すると、InjectScriptの実行終了後もJavaScriptが実行され続ける状況を作ることができます。
実際のワークフローでは次のような設定を行うときに利用します。(※一例)
- ページスクロール
- 一部アクションの省略
ワークフローと平行して動いているJavaScriptの処理は終了する場合には次のアクションを実行します。
- ページ遷移
- ページのリロード
- ワークフローの終了
例として、ワークフローの実行中に、常にページスクロールを行い続ける状態を作る場合、InejectScriptで以下のコードを事前に実行しておきます。
const scroll = function() { const element = document.documentElement; const bottom = element.scrollHeight - element.clientHeight; window.scroll(0, bottom); setTimeout(scroll, 10000); //10秒ごとにスクロールを実行 }; scroll(); //実行開始
# ブラウザを開く_Twitterプロフィール +open_browser_1: action>: OpenBrowser url: 'https://twitter.com/maff_japan' lang: 'ja-JP' headless: true # ページ内でJavaScriptを実行する_スクロールを実行 +inject_script_1: action>: InjectScript browser: +open_browser_1 code: "let scroll = function() {\n let element = document.documentElement;\n let bottom = element.scrollHeight - element.clientHeight;\n window.scroll(0, bottom);\n setTimeout(scroll, 10000); //10秒ごとにスクロールを実行\n};\n\nscroll(); //実行開始\n" waitAfter: 10000 returnValue: false # 繰り返し_5回取得 +loop_1: loop>: 5 _do: # スクリーンショットを撮る_スクロール確認 +take_screenshot_1: action>: TakeScreenshot browser: +inject_script_1 full_page: false type: png waitBefore: 10000
setTimeoutが使用されたInjectScriptで値を出力する方法
setTimeoutを設定すると、InjectScriptの終了後にコードが実行されるため、returnValue(実行時の値を出力)をTRUEに設定しても、値を取得することができません。
setTimeoutを使用したInjectScript内部において、returnValueで値を受け取るためには、JavaScriptのPromise、async/awaitを利用したスクリプトを追加する必要があります。 ここでは例として、async/awaitとsetTimeoutを利用して、InjectScript内部に待機時間を設ける方法を紹介します。スクリプト内部で待機が実行されたことを確認するため、以下の内容をreturnValueさせるスクリプトをInjectScriptに記述します。
injectScriptの開始時刻と、injectScript内部で3秒待機した後の時刻
実行結果と設定内容は、下部の「ワークフロー実行結果」をご参照ください。
スクリプト
// async関数を無名関数として即時実行します。async関数の中でのみ、指定秒の待機が可能です。 // AUTOROはこのasync関数の結果を受け取ります。受け取った結果の型は、returnする値の型が保持されます(強制的にPromise型にはなりません) (async () => { const startTime = new Date().toString(); //injctScriptの開始時刻 const sleep = function(ms) { //msに指定したミリ秒だけ待つ関数、sleepを定義します return new Promise(resolve => setTimeout(resolve, ms)); }; await sleep(3000); //3000ミリ秒(3秒)待機します const endTime = new Date().toString(); //startTimeの3秒後になっています。 return [startTime, endTime]; // 実行されるasync関数の返り値です。開始時刻、開始時刻から3秒後の時刻を返します。 })();
async/awaitはJavaScriptの中でも難しい内容の1つとされます。
「とりあえずInjectScriptのスクリプト内部に待機時間を設けたい」場合は、以下をテンプレートとしてご使用ください。
※InjectScriptのreturnValueパラメータの状態に関係なく使用可能です。
(async () => { const sleep = function(ms) { //msに指定したミリ秒だけ待つ関数、sleepを定義します return new Promise(resolve => setTimeout(resolve, ms)); }; // ここから処理を記述 // 待機したいタイミングで await sleep(ミリ秒)と書けばOKです // 値を出力したい場合は return })(); //InjectScript終了 この下にはユーザ定義関数以外は何も書かないでください
参考
# ブラウザを開く +open_browser_1: action>: OpenBrowser url: 'https://www.google.com/' lang: 'ja-JP' headless: true useShadowDomSelector: false private: false # ページ内でJavaScriptを実行する +inject_script_1: action>: InjectScript browser: +open_browser_1 code: "// async関数を無名関数として即時実行します。async関数の中でのみ、指定秒の待機が可能です。\n// AUTOROはこのasync関数の結果を受け取ります。受け取った結果は、returnする値の型が保持されます(強制的にPromise型にはなりません)\n\n(async () => {\n const startTime = new Date().toString(); //injctScriptの開始時刻\n\n const sleep = function(ms) {\n //msに指定したミリ秒だけ待つ関数、sleepを定義します\n return new Promise(resolve => setTimeout(resolve, ms));\n };\n\n await sleep(3000); //3000ミリ秒(3秒)待機します\n\n const endTime = new Date().toString(); //startTimeの3秒後になっています。\n\n return [startTime, endTime]; // 実行されるasync関数の返り値です。開始時刻、開始時刻から3秒後の時刻を返します。\n})();\n" returnValue: true private: false