在JavaScript中使用setTimeout的模板方法模式

时间:2014-02-08 22:34:55

标签: javascript template-method-pattern

我有一个close函数会关闭某个实例。包含该函数的类允许派生类覆盖close。在这里,我想确保close始终在派生类中调用dispose。我通过以下方式实现了这一目标。

function close() {
  closeCore();
  dispose();
}

function closeCore() {
  // derived class can override this method.
}

这很好用,但我有一个案例,我想在处理实例之前执行CSS动画。这就是我的工作。

function close () {
  instance.classList.add("fancy-animation-that-takes-800ms");

  setTimeout(function () {
    dispose();
  },800);
}

但是一旦我这样做,我使用的模板模式就无法应用。有没有办法确保close函数总是在第二个例子中调用dispose?

1 个答案:

答案 0 :(得分:0)

您可能close期望从closeCore返回一个具有以下参数的对象:

return {timeout: 800, callback: function () {/*....will execute after a timeout..*/}};

或:

return {callback: function () { /*...will be immediately executed...*/}};

或:

return function () { /*...will be immediately executed...*/};

...然后为他们调用超时(如果有的话),然后在超时后执行回调,然后为他们调用dispose

close代码的相关部分可能如下所示:

function close() {
  var ccObj = closeCore();
  var ccIsObj = ccObj && typeof ccObj === 'object';
  var callback = typeof ccObj === 'function' ? ccObj : (ccIsObj ? ccObj.callback : null);
  if (ccIsObj && ccObj.timeout) {
    if (!callback) {
      throw 'You must implement a callback when supplying a timeout';
    }
    setTimeout(function () {
        callback();
        dispose();
    }, ccObj.timeout);
  }
  else {
    if (callback) {callback();}
    dispose();
  }
}

但是如果你想允许用户自己进行任意异步调用(例如Ajax),你可以改为允许返回你添加了dispose调用的promise,你就不会保证派生者确保承诺完成。您可以在一段时间后自动取消承诺,但您无法神奇地知道派生代码何时完成,除非您再抽象一次。