如何在javascript中实现观察者模式?

Ign*_*rat 14 javascript design-patterns observer-pattern

嗨,我想在JavaScript中实现观察者模式:

我的index.js:

$(document).ready(function () {
  var ironMan = new Movie();
  ironMan.setTitle('IronMan');
  ironMan.setRating('R');
  ironMan.setId(1);
  //  ironMan.setCast(['Robert Downey Jr.', 'Jeff Bridges', 'Gwyneth Paltrow']);

  var terminator = new Movie();
  terminator.setTitle('Terminator');
  terminator.setRating('P');
  terminator.setId(2);

  console.log(ironMan.toString());
  console.log(terminator.toString());

  ironMan.play();
  ironMan.stop();
  ironMan.download();
  ironMan.share('V. Rivas');

  console.log(ironMan.getCast()[0]);
});
Run Code Online (Sandbox Code Playgroud)

我的电影:

var title;
var rating;
var id;
var observers;


function Movie() {
  observers = new ObserverList();
}

//function Movie (title, rating, id){
//  this. title = title;
//  this.rating =  rating;
//  this.id =id;
//  observers = new ObserverList();
//}

Movie.prototype.setTitle = function (newTitle) {
  this.title = newTitle;
}

Movie.prototype.getTilte = function () {
  return this.title;
}

Movie.prototype.setRating = function (newRating) {
  this.rating = newRating;
}

Movie.prototype.getRating = function () {
  return this.rating;
}

Movie.prototype.setId = function (newId) {
  this.id = newId;
}

Movie.prototype.getId = function () {
  return this.id;
}

Movie.prototype.play = function () {
  for (i = 0; i < observers.Count; i++) {
    console.log("palying...");
  }
}

Movie.prototype.stop = function () {
  for (i = 0; i < observers.Count; i++) {
    console.log("stoped");
  }
}

Movie.prototype.AddObserver = function (observer) {
  observers.Add(observer);
};
Run Code Online (Sandbox Code Playgroud)

最后观察员:

function ObserverList() {
  this.observerList = [];
}

ObserverList.prototype.Add = function (obj) {
  return this.observerList.push(obj);
};

ObserverList.prototype.Empty = function () {
  this.observerList = [];
};

ObserverList.prototype.Count = function () {
  return this.observerList.length;
};

ObserverList.prototype.Get = function (index) {
  if (index > -1 && index < this.observerList.length) {
    return this.observerList[index];
  }
};

ObserverList.prototype.Insert = function (obj, index) {
  var pointer = -1;

  if (index === 0) {
    this.observerList.unshift(obj);
    pointer = index;
  } else if (index === this.observerList.length) {
    this.observerList.push(obj);
    pointer = index;
  }

  return pointer;
};
Run Code Online (Sandbox Code Playgroud)

你能提供的任何帮助都会让我非常感激.

d13*_*d13 28

JavasScript是事件驱动的:这意味着它意识到时间并期望事情随着时间而改变.最初的观察者模式是为不熟悉时间的C++等语言创建的.您可以通过使用游戏循环来检查状态更改来利用JavaScript的优势.

创建两个DOM元素,一个输入和输出

<input type="text" value="Enter some text...">
<p id="output">
Run Code Online (Sandbox Code Playgroud)

设置一个requestAnimationFrame循环并开始观察.

//Get a reference to the input and output
var input = document.querySelector("input");
var output = document.querySelector("#output");

//Set up a requestAnimationFrame loop
function update () {
  requestAnimationFrame(update);

  //Change the output to match the input
  output.innerHTML = input.value;
}
update(); 
Run Code Online (Sandbox Code Playgroud)

这就是游戏引擎为立即模式渲染所做的事情.它也是React框架检查DOM中状态更改的方法.

(如果你需要它,这里是一个简单的requestAnimationPolyfill)

//Polyfill for requestAnimationFrame
window.requestAnimationFrame = (function(){
  return  window.requestAnimationFrame       ||
          window.webkitRequestAnimationFrame ||
          window.mozRequestAnimationFrame    ||
          window.oRequestAnimationFrame      ||
          window.msRequestAnimationFrame     ||
          function(/* function */ callback, /* DOMElement */ element){
            window.setTimeout(callback, 1000 / 60);
          };
})();
Run Code Online (Sandbox Code Playgroud)


Dmi*_*kiy 12

在JavaScript中,没有必要像在Java中那样实现纯观察者模式,因为JavaScript有一个叫做函数式编程的小东西.所以只需使用像http://api.jquery.com/category/callbacks-object/这样的东西,而不是你的ObserverList.

如果您仍想使用您的对象,那么一切都取决于您想要传递给ObserverList.Add的内容.如果它是某个对象,那么你需要写

for( i = 0; i < observers.Count; i++) { 
  observers[i].Notify("some data"); 
}
Run Code Online (Sandbox Code Playgroud)

如果它是一个函数,那么你需要写

for( i = 0; i < observers.Count; i++) { 
  observers[i]("Some data"); 
}
Run Code Online (Sandbox Code Playgroud)

您还可以使用Function.apply()或Function.call()来提供this您的函数

  • 观察者模式不能被回调替换.使用观察者模式的想法是,您可以看到对象何时发生更改,而不是简单地触发事件或随时调用回调. (6认同)