javascriptでAPIを叩く関数を作ってAPIからデータ取得後にsetTimeout
を使って同じ関数を呼びたいような時 次のような関数を作ったりします。
var timer; // AjaxでAPIを叩いてデータを取得する関数 var getMyAPIData = function() { clearTimeout(timer); $.ajax( url: '/myapi', dataType: 'json', type: 'get', data: postData ) .done( function( res ) { // データが取得できた時の処理 } ) .fail( function( jqXHR, statusText, errorThrown ) { // データ取得に失敗した時の処理 } ) .always( function() { // 1分後後にAPIからデータを取得する timer = setTimeout( function() { getMyAPIData(); }, 60000 ); } ); };
とりあえず、どこかでgetMyAPIData()
を呼び出せば後はAjaxの通信完了から1分後にgetMyAPIData()
が呼び出されるようになります。
この時、初回の関数の呼び出しを直ぐに実行させたいからと即時関数にしてしまうとgetMyAPIData
がundefined
になるのでうまく動作しません。
ダメな例
var timer; // AjaxでAPIを叩いてデータを取得する関数 var getMyAPIData = function() { clearTimeout(timer); $.ajax( url: '/myapi', dataType: 'json', type: 'get', data: postData ) .done( function( res ) { // データが取得できた時の処理 } ) .fail( function( jqXHR, statusText, errorThrown ) { // データ取得に失敗した時の処理 } ) .always( function() { // 1分後後にAPIからデータを取得する timer = setTimeout( function() { getMyAPIData(); // getMyAPIDataが`undefined`なのでエラーになる }, 60000 ); } ); }(); // 初回の呼び出しを即時関数で実行 console.log( getMyAPIData ); // undefined
関数を記述した後にconsole.log(getMyAPIData)
をしてもgetMyAPIData
はundefined
になっているので、即時関数だからalwaysの中で呼び出される変数getMyAPIData
がまだ定義されていない訳ではなく、そもそもundefined
になってしまうのが原因なのです。
return
してないので当たり前といえば、当たり前なのですが、忘れているとハマります。
仮に関数の最後でreturn this;
としてもthis
はwindow
なので期待した結果にはならないかと思います。関数である自身を返すようにするのは少し面倒くさいので素直に関数定義後に関数を呼んであげるのがカンタンかなとおもいます。
c.f
プラスティック・メモリーズ Say to good-bye (1) (電撃コミックスNEXT)
- 作者:祐佑
- 発売日: 2015/04/24
- メディア: コミック