Это потому, что вы говорите с неправильным вызовом prompt
, который находится в обещании, закрытом для другой переменной $str
. Второй и последующие вызовы к блоку prompt
, ожидающие первого вызова до конца sh. Но $str
для получения значения первого вызова выходит за рамки видимости, поэтому ничего не происходит.
Звучит очень странно, но вот эксперимент, который вы можете провести, чтобы помочь вашей интуиции, пока я анализирую это более полно: запустите скрипт, дождитесь тайм-аута, затем введите q
дважды в быстрой последовательности. Сценарий выходит после второго. Почему?
В первом l oop мы объявляем переменную $str
, которую я собираюсь назвать "$str
number 1", и создаем Promise
, закрывающий число $str
1 и звонит prompt
. prompt
присоединяется к STDIN
и не возвращается, пока не увидит новую строку. По истечении времени ожидания этот вызов prompt
не прерывается. Это все еще работает. Все еще жду Обещание, к которому оно прикреплено (назовем его $user
обещание 1), все еще активно, хотя переменная $user
вот-вот выйдет за пределы go.
На втором l oop мы объявите новую переменную $str
("$str
number 2"), создайте Promise
, закрывающий it , и снова вызовите prompt
. Но другой вызов prompt
все еще использует STDIN
, поэтому новый вызов блокируется и ждет, пока STDIN
станет доступным. Если вы наберете что-то сейчас, это будет видно по исходному вызову prompt
, который был прикреплен к $user
обещанию 1 и закрыт по $str
номеру 1.
$str
номер 1 обновлен когда prompt
возвращается, но это не имеет значения, потому что ты перестал на него смотреть. Условие if $str eq 'q'
будет проверять $str
число 2, потому что это переменная, которая была объявлена в текущем l oop.
Второй вызов prompt
затем немедленно запрашивает ввод, и если вы наберете q
до истечения времени ожидания, он обновит версию $str
, которую он закрыл, $str
номер 2. Поскольку это та, которую проверяет ваше условие, l oop завершается.
Каждый тайм-аут начинает новый prompt
без завершения старого, что означает, что вводимые пользователем данные никогда не присоединяются к тому же $str
, который вы проверяете. Даже если вы осмотрите исходную переменную, последующие вызовы prompt
все равно будут происходить и будут продолжать запрашивать даже после того, как выполнение покинуло блок.
Поскольку prompt
не имеет способа указать время ожидания и У Раку нет способа «убить» запланированное Promises
, я не думаю, что вам удастся решить эту проблему с prompt
.