JS и проблемы параллелизма? - PullRequest
4 голосов
/ 21 марта 2012

Предположим, у меня есть простой код;

var counter = 0;
var sharedResource = [];//some shared resource

function incrementAndModify(){
   if(counter == 0) {
      sharedResource.push(Math.random());//very sensitive data
      counter++;
   }
}

function init(){
    incrementAndModify();
    doAjaxGetWithCallback(function(){incrementAndModify();});
    incrementAndModify();
}

Итак, вопрос в том, будет ли функция incrementAndModify () выполняться атомарно или нет? Я читал, что JS работает в одном потоке, и не может быть проблем с параллелизмом. Но вопрос все еще открыт (по крайней мере для меня).

вместо

doAjaxGetWithCallback(function(){incrementAndModify();});

Я мог бы написать что-то вроде:

doAjaxGetWithCallback(function(){
doSomeCrazyStuffThatDoesNotUseSharedResource();
incrementAndModify();
doSomeOtherCrazyStuffThatDoesNotUseSharedResource();
});

Ответы [ 3 ]

3 голосов
/ 21 марта 2012

JavaScript в браузере является однопоточным (за исключением с), поэтому вам не нужно беспокоиться о параллелизме.По сути - каждый блок кода является атомарным, независимо от того, как долго.Если incrementAndModify() выполняет некоторые очень трудоемкие операции, требующие много времени, и приходит ответ AJAX, обратный вызов не будет выполнен, пока текущий incrementAndModify() не завершит работу и не освободит единственный поток.

Это также причина, по которойсинхронные вызовы AJAX не приветствуются: запрос AJAX может занять некоторое время, в течение которого другой код не может быть выполнен (поток выполнения неоправданно занят).Это приводит к «зависанию» GUI, поскольку никакие другие пользовательские события не обрабатываются.

См. Также

Кстати, это:

doAjaxGetWithCallback(function(){incrementAndModify();});

можно записать так:

doAjaxGetWithCallback(incrementAndModify);
0 голосов
/ 17 июля 2015

Да, функция incrementAndModify() всегда будет работать атомарно.Это из-за функции Run-to-Completion в javascript.

См. Почему нет инструмента управления параллелизмом в javascript для более подробной информации.

0 голосов
/ 21 марта 2012

Не бойтесь, это будет только один раз.

// sync example
var happened = false;

setTimeout(dontDoTwice, 0);
setTimeout(dontDoTwice, 0);
setTimeout(dontDoTwice, 0);

function dontDoTwice() {
  if (!happened) {
    alert("ALERT! ALERT! ALERT!");
    happened = true;
  }
}

Чуть более сложный пример: http://jsfiddle.net/7BZ6H/1/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...