Существуют ли какие-либо атомарные операции JavaScript, чтобы справиться с асинхронной природой Ajax? - PullRequest
14 голосов
/ 01 сентября 2011

Я динамически загружаю код (функции) с сервера и выполняю его как код JavaScript, затем сохраняю его в массиве и выполняю.Все эти фрагменты кода должны быть выполнены ровно один раз.Псевдокод выглядит следующим образом:

function fetch(foo){
    if (foo in fooArray){
          //Do Nothing
    else{
          //Fetch foo via Ajax and execute foo()
    }
}

Проблема гораздо сложнее, но, по сути, если я введу приведенную ниже команду

fetch('someFunctionName');
fetch('someFunctionName');
fetch('someFunctionName');
fetch('someFunctionName');

, все четыре выполнят команду if (foo in fooArray) и примутотсутствует в массиве, и все четыре продолжат извлекать код и выполнять его.Я помню, как в те дни, узнав о семафорах и мьютексах, существуют ли такие вещи для javascript.

Ответы [ 2 ]

32 голосов
/ 01 сентября 2011

JavaScript - хороший язык, который отлично работает с асинхронными обратными вызовами, тайм-аутами, интервалами и пользовательскими событиями, но не имеет проблем с параллелизмом.Это возможно, потому что JavaScript по сути однопоточный - данный фрагмент кода всегда выполняется атомарно и никогда не прерывается другим потоком, выполняющим JavaScript.

Ваша fetch() функция всегда будет выполняться без какого-либо прерывания.Если он выполняется как часть обратного вызова AJAX и если ожидают несколько обратных вызовов AJAX, они будут поставлены в очередь.

Другой пример: если у вас есть обработчик события, назначенный элементу ввода, и вы запускаете событие несколько разобработчики событий не будут выполняться одновременно.Вместо этого они будут поставлены в очередь и выполнены последовательно.Это также относится к нескольким событиям, инициируемым setTimeout() / setInterval().

. В качестве примечания: это одна из причин, по которой node.js является настолько надежным: он используеттолько один поток и никогда не блокирует ввод / вывод, но вместо этого использует обратные вызовы, когда данные готовы / происходит событие.

1 голос
/ 24 февраля 2012

Javascript по сути однопоточный, поэтому вам не нужен мьютекс. Ваша выборка могла бы установить флаги так, чтобы последующие вызовы выборки могли избежать вызовов ajax, например ::100100

var beingFetched = {};//map onflight -> callbacks
function fetch(foo){
  if (foo in fooArray){
      //Do Nothing
  } else {
      if (beingFetched.foo) { //note empty array is truthy
          //register a callback
          var callback = function(r){
             //anything you need to do wit the return object r
             //maybe even eval it.
          };
          //the callback would more likely be an argument to fetch itself
          //or you could use a promise API instead so that you can at your will
          //register multiple callbacks - for error, for success etc.
          beingFetched.foo.push(callback); 
      } else {
          beingFetched.foo = [];//truthy
          //Fetch foo via Ajax and execute
          $.ajax("getFoo/"+foo).done(function() {
              _.each(beingFetched.foo, function(cb){
                  cb.apply(cb,arguments);
              });
              delete beingFetched.foo;
          });
      }
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...