Реентерабельность в JavaScript

Я хотел бы улучшить свое понимание слова «реентерабельность».

Эта функция реентерабельна?

function* foo() {
  yield 1;
  yield 2;
}

И этот?

function foo() {
  return 1;
}

И этот?

var x = 0;
function foo() {
  return x++;
}

И этот?

function foo() {
  setTimeout(foo, 1000);
}

person Ben Aston    schedule 07.12.2015    source источник
comment
См. stackoverflow.com/questions/2799023/ тоже, это вопрос, связанный с C ++, но ответ остается прежним.   -  person Gerrit Bertier    schedule 07.12.2015
comment
В случае, если кому-то интересно - это не повторяющийся вопрос, поскольку он не касается JavaScript, а C ++ имеет другую модель выполнения.   -  person Benjamin Gruenbaum    schedule 07.12.2015
comment
@ Бен Привет, ты нашел "правильный" ответ, не могли бы вы поделиться им с нами?   -  person SmallTown NE    schedule 15.04.2018


Ответы (1)


Повторяющаяся функция - это функция, выполнение которой может быть возобновлено:

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

В JavaScript браузера / узла вся многопроцессорность является кооперативной (без прерываний или переключений контекста). Обычная функция всегда выполняется до завершения в JavaScript. (1)

Итак, в вашем случае - единственная повторная функция является первой, поскольку она не выполняет свой код до завершения и может быть возобновлена ​​позже.

  • Вторая функция - это обычная функция.
  • Третий использует внешнюю область видимости, которая в некотором роде похожа, потому что позволяет функции удерживать некоторое состояние. Но это не то же самое, поскольку функция не может быть возобновлена.
  • Четвертый запускается сразу до завершения (он планирует еще один его вызов, но это зависит от платформы, а не JavaScript).

В самом деле - можно сказать, что генераторы обеспечивают совместную многозадачность в JavaScript с повторно используемым синтаксисом. Перед генераторами весь код работал до конца.

(1) Или он никогда не останавливается, но никогда не прерывается. Также - в общих платформах. Существуют платформы (например, Rhino), которые нарушают правила. Они очень редки и не используют ту же модель выполнения параллелизма, что и JS браузера / узла.

person Benjamin Gruenbaum    schedule 07.12.2015
comment
Почему 2 не реентерабельна? Хотя модель выполнения javascript не позволяет вызывать его несколько раз одновременно, она по-прежнему является реентерабельной. Все обычные функции реентерабельны. - person Sulthan; 07.12.2015
comment
Потому что его нельзя прервать в середине его выполнения, а затем безопасно вызвать снова до того, как его предыдущий вызов завершит выполнение - просто и понятно. Проще говоря, его просто нельзя прерывать посреди его выполнения. Это не похоже на генераторы, которые могут объявлять точки прерывания (урожайности) и доводить их до завершения. - person Benjamin Gruenbaum; 07.12.2015
comment
Нет. Просто нет. Это противоречит определению. Вы можете вызвать (2) несколько раз одновременно, и он все равно будет возвращать тот же результат. Вот что делает его реентерабельным. Тот факт, что JS не поддерживает параллельное выполнение, не имеет к этому никакого отношения. Определение повторного входа не отличается для разных языков. - person Sulthan; 07.12.2015
comment
JS поддерживает параллельное выполнение (только не потоки, ну, платформы JS работают на do). Я думаю, что вам не хватает того, что повторный ввод требует, чтобы функция могла быть прервана для начала с. - person Benjamin Gruenbaum; 07.12.2015
comment
Фактически, @freen-m вызывается несколько раз с одними и теми же аргументами, что приводит к одному и тому же результату - чистоте. Идемпотентность означает, что вызов его несколько раз имеет тот же эффект, что и его однократный вызов. - person Benjamin Gruenbaum; 07.12.2015
comment
Это было просто упрощением определения. Я все еще не согласен. Все чистые функции (например, (2)) автоматически реентерабельны. Одним из основных условий повторного входа является то, что повторно входимый код не может вызывать нереентерабельные подпрограммы. Если вы скажете, что (2) не является реентерабельным, вы не сможете выполнить это условие. - person Sulthan; 07.12.2015
comment
@Sulthan Если вы не согласны с этим ответом, укажите свой, и сообщество сможет прийти к консенсусу. - person Ben Aston; 07.12.2015