реагировать на поставку из последовательности - PullRequest
6 голосов
/ 10 марта 2019

Я не могу понять, почему эта программа работает:

my $supply = Supply.interval: 1;

react {
  whenever $supply       { put "Got $^a"  }
  whenever Promise.in(5) { put 'Timeout!'; done }
}

END put 'Ending…'

печать это:

Got 0
Got 1
Got 2
Got 3
Got 4
Timeout!
Ending…

и правильно выходит, а вот этот:

my $supply = (1, 1, * + * … ∞).Supply;

react {
  whenever $supply       { put "Got $^a"; sleep 1 }
  whenever Promise.in(5) { put 'Timeout!'; done }
}

END put 'Ending…'

печать

Got 1
Got 1
Got 2
Got 3
Got 5
Timeout!

но затем он зависает и не выводит "Завершение ..."; разве «сделано» не достаточно в этом случае?

Если я заменю «done» на «exit», программа будет работать нормально и завершится.

1 Ответ

4 голосов
/ 11 марта 2019

Это всего лишь предположение:

A done в блоке whenever сигнализирует, что подача для этого whenever завершена. В этот момент react готов к выполнению в целом, но сначала он позволяет другим припасам завершить все, что они ждут, если что.

В первом случае первый whenever источник ($supply) выдает другое значение каждую секунду. Он не будет готов, когда Promise.in(5) поставка done. Итак, все react сделано.

Во втором случае первый источник питания whenever ($supply) мгновенно испускает другое значение. А потом еще. Это никогда не готово. Таким образом, общий react никогда не делается. Вместо этого react продолжает находить первый whenever готовый, поэтому cue s другой блок, а затем повторяется это миллионы раз, и эти блоки никогда не запускаются и не выполняют свои put потому что система слишком занята, порождая миллионы потоков.

...