在继续之前等待对象构造函数内的方法完成

时间:2015-09-03 02:10:31

标签: javascript asynchronous

我正在构建一个计时器,从25分钟到0分钟,然后从5分钟到0分钟。现在,我有一个CountDownTimer对象,其参数为25 * 60,从25到0计数。我想启动一个新的计时器,一旦另一个计时器达到0,将从5计数到0。如何实现这种类型的异步代码,然后执行X次异步代码?

$(document).ready(function(){
  var sessionBreakTimer = new CountDownTimer(25*60);
  sessionTimer.start();
  if (!sessionTimer.isRunning) {
    sessionBreakTimer.start();
  }
);

function CountDownTimer(secs) {
  var duration = secs;
  var running = false;

  this.start = function() {
    running = true;
    var startT = new Date().getTime();
    var intervalId = window.setInterval(function() {
      var msDelta = new Date().getTime() - startT; // milliseconds elapsed since start
      var secsLeft = duration - Math.floor(msDelta / 1000);
      if (secsLeft === 0) {
        window.clearInterval(intervalId);
        console.log("cleared");
        running = false;
      }
    }, 1000); //update about every second
  };

  this.isRunning = function() {
    return running;
  }

}

2 个答案:

答案 0 :(得分:1)

您可以向callback添加countdown方法并设置它,以便在达到0秒时调用正确的计时器。像这样举例如:

function CountDownTimer(secs) {
  var self = this;
  var duration = secs;
  var running = false;

  this.callback = function(){}; //This will allow you to define this afterwards

  this.start = function() {
    running = true;
    var startT = new Date().getTime();
    var intervalId = window.setInterval(function() {
      var msDelta = new Date().getTime() - startT; // milliseconds elapsed since start
      var secsLeft = duration - Math.floor(msDelta / 1000);
      if (secsLeft === 0) {
        window.clearInterval(intervalId);
        console.log("cleared", secs);
        running = false;
        self.callback();//your callback is being called here
      }
    }, 1000); //update about every second
  };

  this.isRunning = function() {
    return running;
  }

}

你定义它是这样的:

$(document).ready(function(){
  var sessionBreakTimer = new CountDownTimer(25*60);
  var sessionTimer = new CountDownTimer(5*60);
  sessionBreakTimer.callback = sessionTimer.start;//sessionTimer will be called when breaktimer is over
  sessionTimer.callback = sessionBreakTimer.start;//and vice versa
  sessionTimer.start();

});

http://jsfiddle.net/bw0nzw3m/1/

如果您希望仅执行特定次数的操作,则每次调用计时器时都需要一个变量来计数,当它结束时,您将回调设置为函数完成行为或根据您的需要只是一个空函数。

答案 1 :(得分:1)

尝试使用Promise

var intervalId,
  // current count
  count = 0,
  // current stop
  stop = 2,
  // cycles of `session`
  ticks = 0,
  // cycles of `session` to call
  total = 2,
  counter = function counter(session) {
    var fn = function fn() {
      // call `CountDownTimer.start()`
      return new CountDownTimer(session[count]).start()
        .then(function(data) {
          console.log(data);
          // recursively call `counter`
          return counter(session)
        })
    }
    return count < stop ? fn() : (function() {
      // increment `ticks`
      ++ticks;
      // reset `count` to `0`
      count = 0;
      return ticks < total 
             ? fn() 
             // do stuff when `ticks` equal to `total`
             : Promise.resolve({
                 count: count,
                 ticks: ticks,
                 total: total
               })
    }())
  }

function CountDownTimer(secs) {
  var duration = secs;
  var running = false;
  countdown = this;
  this.start = function() {
    // return `Promise` object from `CountDownTimer.start`
    return new Promise(function(resolve) {
      running = true;
      var startT = new Date().getTime();
      intervalId = window.setInterval(function() {
        // milliseconds elapsed since start
        var msDelta = new Date().getTime() - startT;
        var secsLeft = duration - Math.floor(msDelta / 1000);
        console.log(secsLeft);
        if (secsLeft === 0) {
          window.clearInterval(intervalId);
          // increment `count`
          ++count;
          console.log("cleared");
          running = false;
          resolve({
            count: count,
            ticks: ticks,
            total: total
          })
        }
      }, 1000); //update about every second
    })
  };

  this.isRunning = function() {
    return running;
  };

}
// settings for `sessions`
// set to 60 seconds, 30 seconds for stacksnippets
var sessions = [1 * 60, 0.5 * 60];
// var sessions = [25 * 60, 5 * 60];

counter(sessions)
// do stuff when all cycles of `ticks` complete
.then(function(data) {
  console.log("complete:", data)
});