1

以下は、2つのアセットパイプラインファイルに同じ名前を使用しないことで回避できるため、それ自体は問題になりません。説明に興味があるので、洞察に感謝します。

これはRails3.2.6、スプロケット2.1.4です(最新の2.4.4でも試してみました)。最小限の例: http: //github.com/richardkmichael/js-test

私はを持っていてFooController、coffeescriptではなくjavascriptを書いているので、新しいファイルを作成しましたfoo.jsが、空のままにしましたfoo.js.coffee

readyState === 'complete'clearInterval()で停止するsetInterval()関数(テスト)があります。ただし、interval関数は、clearInterval()呼び出しが機能していないかのようにループします。

空のfoo.js.coffeeファイルを削除すると、ループが停止し、JSは期待どおりに機能します。空を置き換えるfoo.js.coffeeと、クライアントでループ動作が再開されます。

サーバー側の処理がクライアント側で何かを変更しているように見え、リセット/新しい間隔タイマーが発生しますか?

これら2つのケースの間にクライアント側のJSの違いはないようです。ただし、Chromeのウェブインスペクターでは:

  • 「リソース」リストは1回だけで、どちらの場合もサーバー側 foo.jsに表示されるJSが正確に含まれています。セミコロンが1つ含まれています。(余談ですが、jQueryを削除しても、このループ動作は残ります。)foo.jsapplication.js

  • 「ソース」(localhost /アセット)はfoo.js?body=12回リストされます。

app/controllers/foo_controller.rb

class FooController < ApplicationController
  def index
    render :inline => '<p>Hello, World!</p>', :layout => true
  end
end

app/assets/javascripts/foo.js

var readyStateCheckInterval = setInterval(function () {
  if (document.readyState === 'complete') {
    console.log('Document ready.');
    clearInterval(readyStateCheckInterval);
  }
}, 2000);

app/assets/javascripts/foo.js.coffee

<empty -- just `touch .../foo.js.coffee`>

(おそらく)同様の質問:スプロケットの重複ファイルの命名

アップデート

回答に基づいて、2つの<script>タグがあることに気づきました(後から考えるとかなり明白です)。Frederickの説明をテストして、最初のタイマー参照が失われないようにjavascriptを変更しました。これはconsole.log、期待どおりに「機能」します(正確に2回の書き込み)。

/*jslint indent: 2 */

(function () {

  'use strict';

  var intervalTimers = {},
    date = new Date(),
    time = date.getTime();

  function setupIntervalTimer(name) {
    intervalTimers[name] = setInterval(function () {
      if (document.readyState === 'complete') {
        console.log('Document ready.');
        clearInterval(intervalTimers[name]);
      }
    }, 2000);
  }

  setupIntervalTimer(time);

}());
4

1 に答える 1

3

Your Javascript is being included twice. The network inspector is likely only showing it once because the browser is smart enough not to fetch the same file again

When your first copy of the Javascript runs it creates your timer and stashes its value in readyStateCheckInterval so that it can cancel it later. The second copy creates a second timer and overwrites the value of readyStateCheckInterval with the new value. Your callbacks then end up trying to cancel the second timer twice but never cancel the first one (since you've now lost your reference to it)

于 2012-07-10T17:38:21.930 に答える