setTimeout()とのsetInterval()ソースコード解析

なぜなら、動的レンダリングページの必要性の最近開発プロセスで、私は、ページデータを更新する必要がありますする必要はなく、ブラウザがお客様のデータに基づいて動的にレンダリングすることができませんが、この時間は、のsetInterval関数を使用しますが、この機能とのsetTimeout ()、それはどのような違いを生むんに比べて?我々はそれを知っています:

  • setTimeoutメソッド(メソッドは、ブラウザのウィンドウにバインドされている、あなたはどのように多くのミリ秒(ms)の実行中にこのメソッドまたは関数でコードを指定して、タイマーの数を返すことができます)、もちろん我々はてclearTimeout(でコードを取り消すことができます)実行
  • ブラウザウィンドウにバインドするのsetInterval()メソッド、あなたはどのように多くのミリ秒(ms)実行のタイミングによってコードや関数のsetIntervalの一部を指定し、タイマーの数を返すことができ、もちろん我々はてclearInterval(でコードを取り消すことができます)実装
    :最も効果的かつ直接的には、下の少し実験感じている
    コードは、到着を実行した場合、時間が来ているか否かが判断され、コードのターンが実行されるまで、実際にタスクキューに追加されて実行する必要があるだろうのsetInterval()メソッドのコードの実行を
    var startTime=new Date();
    var func = function(){
    console.log('start: ' + (new Date()-startTime));
    for(var i=0; i<1000000000; i++){}
    console.log('end: ' + (new Date()-startTime));
    };
    setInterval(func,1000);

    上記のコードを実行した後、あなたがたsetInterval終わりを見つけて、非常に大規模な暴行時間を開始します、我々は1000ミリ秒に設定されていません。setIntervalは、開始点キャリブレーション実行時間があるので、とき、それは修正されません1000ミリ秒以上の登録機能(FUNC)。
    setTimeout()とのsetInterval()ソースコード解析
    setTimeout()使用は、実行のタイミングことを除いて、我々はまた、遅延現象をテストするために実行、実質的に同一のsetInterval

    var startTime=new Date();
    var func = function(){
    console.log('start: ' + (new Date()-startTime));
    for(var i=0; i<1000000000; i++){};
    console.log('end: ' + (new Date()-startTime));
    setTimeout(func,1000);
    };
    setTimeout(func,1000);

    チャートは、コードが現在発生し得る状況の実装ではタスクキューおよび遅延を実行されるため、我々は、上記のコードことがわかりFUNCエンドを実行し、時間間隔を開始するに沿って基本的にあることができ、インターバル設定のsetTimeout観測時間の下で見つけることができます私たちのセット1000msでは
    setTimeout()とのsetInterval()ソースコード解析
    超えて見て、私たちは、この2つの関数のソースコードを見て可能性がある
    setTimeout()とのsetInterval()ソースコード解析
    関数の宣言から、ここでのsetIntervalを知ることができる方法は、私たちが通過し、それが一定時間(数)で実行させる、ことができ、質量参加することができますスケジューラに依存した時間を待っ_schedulerて、メソッドを実行することである_fnAndFlushとして、しかし、規制を担当する_requeuePeriodicTimer時間間隔は、我々が提供されていないこの方法の固定1000msの存在

....
case 'setInterval':
  task.data!['handleId'] = this._setInterval(
      task.invoke, task.data!['delay']!,
      Array.prototype.slice.call((task.data as any)['args'], 2));
  break; 
....

private _setInterval(fn: Function, interval: number, args: any[]): number {
  let id = Scheduler.nextId;
  let completers = {onSuccess: null as any, onError: this._dequeuePeriodicTimer(id)};
  let cb = this._fnAndFlush(fn, completers);

  // Use the callback created above to requeue on success.
  completers.onSuccess = this._requeuePeriodicTimer(cb, interval, args, id);

  // Queue the callback and dequeue the periodic timer only on error.
  this._scheduler.scheduleFunction(cb, interval, args, true);
  this.pendingPeriodicTimers.push(id);
  return id;
}  

初めて目_fnAndFlushのコードでは、この機能は、ブラウザが実行するのを待っている、実際にメモリにブラシを実行するために私たちの必要性の関数であり、

private _fnAndFlush(fn: Function, completers: {onSuccess?: Function, onError?: Function}):
    Function {
  return (...args: any[]): boolean => {
    fn.apply(global, args);

    if (this._lastError === null) {  // Success
      if (completers.onSuccess != null) {
        completers.onSuccess.apply(global);
      }
      // Flush microtasks only on success.
      this.flushMicrotasks();
    } else {  // Failure
      if (completers.onError != null) {
        completers.onError.apply(global);
      }
    }
    // Return true if there were no errors, false otherwise.
    return this._lastError === null;
  };
}

私たちは、見て可能性がある_requeuePeriodicTimer機能を完了するには、この方法の特徴。その機能は、機能の完全なプロセスは、すなわち、次の機能のために待機中の実行中にタイマー機能を持って、スケジューラの次の実行サイクルに入った追加メモリ、ブラウザの実行キュー(存在する場合)に存在しています実行。実験として、スタート間隔のすべてが、私たちは約1000ミリ秒を観察します

private _requeuePeriodicTimer(fn: Function, interval: number, args: any[], id: number): Function {
  return () => {
    // Requeue the timer callback if it's not been canceled.
    if (this.pendingPeriodicTimers.indexOf(id) !== -1) {
      this._scheduler.scheduleFunction(fn, interval, args, true, false, id);
    }
  };
}

実行後、一定時間(数)で、待つその時間はスケジューラ_schedulerに依存するが、スケジューラ機能は、私たちの設定時間間隔を満たすためにするものであるようにsetTimeoutメソッドのためにここで、我々はパス1を許可する、質量参加することができますsetTimeoutメソッドをキューにプッシュされた機能を実行しないので、前のサイクルに入った後、機能が完了するまでのタイマーを実行するために開始されませんので、1000ミリ秒の実装、および_fnAndFlushによって方法の理由は、規制のために責任があります1000ミリ秒で書かれた待機実験コードとして次のサイクル、

...
case 'setTimeout':
  task.data!['handleId'] = this._setTimeout(
      task.invoke, task.data!['delay']!,
      Array.prototype.slice.call((task.data as any)['args'], 2));
  break;
...
private _setTimeout(fn: Function, delay: number, args: any[], isTimer = true): number {
  let removeTimerFn = this._dequeueTimer(Scheduler.nextId);
  // Queue the callback and dequeue the timer on success and error.
  let cb = this._fnAndFlush(fn, {onSuccess: removeTimerFn, onError: removeTimerFn});
  let id = this._scheduler.scheduleFunction(cb, delay, args, false, !isTimer);
  if (isTimer) {
    this.pendingTimers.push(id);
  }
  return id;
}   

参考:
https://www.jeffjade.com/2016/01/10/2016-01-10-javacript-setTimeout/
https://www.jeffjade.com/2016/01/10/2016-01-10 -javaScript-のsetInterval /

おすすめ

転載: blog.51cto.com/yerikyu/2434534