Использование jquery $ .ajax вызывает блокировку браузера с помощью arbor.js, а «родной» JSON - нет? - PullRequest
1 голос
/ 12 апреля 2011

Я создаю форсированный граф данных semanticproxy.com, используя этот ответвление . У меня есть основной объект Explorer, который контролирует узлы (далее сокращенно):

function Explorer(canvas) {
  // set up particle system
  this.ps = arbor.ParticleSystem(1000, 600, 0.5);
  this.ps.renderer = Renderer(canvas);
  this.canvas = $(canvas).get(0);

  var self = this;

  $('body').bind('subjectFound', function(event, sourceNode, targetName, targetRelevance) {
    self.addEdge(sourceNode, targetName, targetRelevance);
  });
}

Explorer.prototype.addEdge = function(source, target, relevance) {  
  var target = this.ps.addNode(target);
  if (source != target) this.ps.addEdge(source, target, {relevance:relevance});
}

// start the explorer up on a new subject
Explorer.prototype.start = function(name) {
  var node = this.ps.addNode(name);
  node.populate(this.ps);
};

var xplor = new Explorer("#viewport");
xplor.start("Andreas Michl");

Вы заметите, что метод start () добавляет узел в систему частиц (прекрасно работает), а затем заполняет этот узел. Вот код для узла, частично (обратите внимание, что я дополняю прототип узла arbor.js):

// fills this node with data from SemanticProxy
Node.prototype.populate = function() {
  var self = this;

  // get the semantic data for this subject      
  // setup the handler function
  var functionName = "subjectHandler" + new Date().getTime();
  window[functionName] = function(data) {
    // invoke function with saved context and parameter    
    self._fillFromSP.call(self, data);    
  }
  var url = "http://service.semanticproxy.com/processurl/"+SP_KEY+"/jsonp:"+functionName+"/http://en.wikipedia.org/wiki/"+this.name;
  $.ajax({url: url, dataType: "script", type: "GET", cache: false, callback: null, data: null});
};

// fills this subject with data from SemanticProxy
Node.prototype._fillFromSP = function(data) {
  var self = this;
  $.each(data, function(key, val) {
    if (key != "doc") {
      if (val.name && val.relevance) {
        $('body').triggerHandler('subjectFound', [self, val.name, val.relevance]);
      }
    }
  });
}

Таким образом, как только данные семантического прокси возвращаются, он должен вызвать обработчик subjectFound в объекте Explorer и добавить узел, как это было раньше с первым узлом. Но он каждый раз задыхается - диаграмма блокируется, и использование одного из моих ядер процессора достигает 100% (Firefox и Chrome).

Однако, если я изменю метод populate на следующий, он будет работать нормально:

Node.prototype.populate = function() {
  var self = this;

  // get the semantic data for this subject
  // setup the handler function
  var functionName = "subjectHandler" + new Date().getTime();
  window[functionName] = function(data) {
    // invoke function with saved context and parameter    
    self._fillFromSP.call(self, data);    
  }
  window[functionName](json);
};

var json = {"doc":{"info"  ...  "length":48}]}};

где переменная json содержит данные из того же URL-адреса семантического прокси, что и раньше. Все соответствующие узлы появляются и красиво отображаются. Так что только когда я использую вызов $ .ajax, и только когда данные действительно возвращаются в мой браузер, они блокируются. Я могу пройтись по коду, и он вызывает $ ('body'). TriggerHandler с правильными параметрами правильное число раз. Он успешно запускает все при вызове Explorer.addEdge (), где системе частиц arbor сказано добавить несколько узлов - и тогда это не работает. Но только при использовании вызова AJAX!

Есть идеи? Заранее спасибо.

Обновление: Я просто настроил небольшой контроллер Rails для использования в качестве прокси. Не повезло тоже. Вместо вызова $ .ajax и странного обработчика окна в методе populate я просто выполнил:

var url = "http://localhost:3000/?url=http://service.semanticproxy.com/processurl/8bv73k5hgj9prkhee9rrr9s4/json/http://en.wikipedia.org/wiki/Andreas_Michl";
$.getJSON(url, function(data) {
  self._fillFromSP(data); 
});

Но это было то же самое поведение - запирание Может быть, состояние гонки или что-то еще в коде беседки?

Решение

Метод заполнения теперь читает:

// fills this node with data from Wikipedia and SemanticProxy
Node.prototype.populate = function() {
  var self = this;

  // get the semantic data for this subject  
  var ajaxWorker = new Worker('javascripts/worker_ajax.js');
  ajaxWorker.onmessage = function(event) {    
    self._fillFromSP(event.data);
  };
  ajaxWorker.postMessage({name: this.name});
};

и worker_ajax.js:

onmessage = function(event) {
  var SP_KEY = "xxxx";
  var url = "http://service.semanticproxy.com/processurl/"+SP_KEY+"/jsonp:handle/http://en.wikipedia.org/wiki/"+event.data.name;
  importScripts(url);
}

var handle = function(json) {
  postMessage(json);
}

1 Ответ

1 голос
/ 12 апреля 2011

WebWorkers и JSONP не сочетаются друг с другом, поскольку у WebWorkers нет DOM, к которому можно прикреплять элементы, другими словами, вы не можете прикрепить свой тег сценария ни к чему.http://cggallant.blogspot.com/2010/10/jsonp-overview-and-jsonp-in-html-5-web.html

Что касается использования JQuery в Webworkers, взгляните на эту тему: HTML Web Worker и Jquery Ajax call

...