26.08.2008, 15:00
|
Интересующийся
|
|
Регистрация: 23.08.2008
Сообщений: 20
|
|
Сообщение от Kolyaj
|
Ну если по теме: в JavaScript функции -- объекты первого типа
|
Это явно из какой-то теории. По сему вопрос - какие типы ещё бывают и чем отличаются (кроме номеров)? Ну это так, из спортивного интереса.
Сообщение от Kolyaj
|
... открывает такие возможности написания простого и лаконичного кода, который ObjectPascal'ю даже не снился.
|
Цены бы Javascript не было, если бы можно было реализовать то с чего тема начата была...
А так остается только приспосабливаться к особенностям языка.
|
|
02.08.2011, 06:55
|
Профессор
|
|
Регистрация: 11.05.2011
Сообщений: 241
|
|
Мнэээ... наткнулся тут на эту тему. И чисто для справки тем кто как и я будут читать архив, вставлю, что я пока в JavaScript не большой специалист, но в Delphi тоже можно передавать функции как параметры - по ссылке, и возвращать как результат работы. Более того, есть даже возможность описывать типы как функции. Например можно сделать массив или список функций.
И еще - почитал тут в инете, что вроде можно в JavaScript использовать window.postMessage, так что какая-никакая обработка сообщений в нем есть и соответственно это касается вопроса топикстартера. Он не про многопоточность спрашивал, а про передачу управления в очередь обработки сообщений, пока происходит ожидание - заметьте, что это именно в однопоточном приложении. И насколько я понял - если пользоваться очередью сообщений, написав свой ProcessMessages, то только в IE скрипт будет блокироваться, а в других браузерах будет работать асинхронно.
Последний раз редактировалось Почемучкин, 02.08.2011 в 06:58.
|
|
06.09.2014, 15:57
|
Новичок на форуме
|
|
Регистрация: 06.09.2014
Сообщений: 2
|
|
Извините, но в выложенных примерах пока никак не разобрался, может быть, позднее разберусь, когда прочту весь учебник.
Очень хотелось бы сделать, чтобы браузер не зависал при длительном вычислении, то есть чтобы рекурсивная функция длительного перебора не препятствовала другим процессам. Очень хотелось бы найти аналог Application.ProcessMessages в javascript, который позволял бы, например, идти часам во время работы программы.
Браузер Firefox зависнет на целую минуту в Судоку-онлайн для примера 3, пока программа сделает 3 миллиона переборов, а в для примера 46 зависнет на целых 2 минуты, пока программа сделает 9 миллионов переборов.
Вот здесь добавил часы на страничку
sudokut.htm
, и если вы попробуете решить пример 3 или пример 46, то увидите, что во время работы программы часы остановятся.
Скрипт программы.
Подвешивает браузер вот этот код.
function recfrugal(k)
{
var i;
var j;
var t;
var q;
if (k == 82)
{
u++;
for (i = 1; i <= 81; i++) z[i][u] = s[i]
}
if ((k <= 81) && (u < 10))
{
if ((w[k] == 0) || (w[k] == 1)) recfrugal(k+1);
if (w[k] > 1)
{
for (t = 1; t <= w[k]; t++)
{
q = true;
for (j = 1; j <= 20; j++) if (b[k][t] == s[m[k][j]]) q = false;
if (q == true)
{
s[k] = b[k][t];
c++;
recfrugal(k+1);
}
}
s[k] = 0;
c++;
}
}
}
Что конкретно надо добавить в код программы, чтобы зависание браузера во время длительных вычислений не происходило?
В Паскале (Лазарусе) достаточно было для этого дописать в код функции одну только строчку Application.ProcessMessages
Цитата:
|
procedure recgen(k: integer; h: integer; g: integer);
var
i: integer;
j: integer;
t: integer;
q: boolean;
begin
Application.ProcessMessages;
if k = size*size + 1
then
begin
u0:=u0+1;
Form2.EditNumberOfSolutions.Text:=IntToStr(u0);
randomize;
randomfield;
for i:=1 to size*size do
if r[i]<=h
then gen[i]:=sg[i]
else gen[i]:=0;
rank(g);
end;
if (k<=size*size) and (stop=false) and (u<>g)
then
begin
randomize;
randomingnumber;
for t := 1 to size do
begin
q := true;
for j := 1 to mc[k] do
if y[t] = sg[m[k, j]]
then q := false;
if (q = true)
then
begin
sg[k] := y[t];
recgen(k+1, h, g);
end;
end;
sg[k] := 0;
end;
end;
|
А что является аналогом Application.ProcessMessages в javascript?
|
|
06.09.2014, 16:09
|
|
Тлен
|
|
Регистрация: 02.01.2010
Сообщений: 6,588
|
|
JS однопоточный язык. Нет в нём изначально никаких "других" процессов. Остановка - есть остановка всего на странице.
Современное решение: web worker. Он создаёт отдельный поток из отдельного скрипта, что общается с основным потоком сообщениями.
По старинке: дробить вычисления setTimeout'ами.
__________________
29375, 35
Последний раз редактировалось Aetae, 06.09.2014 в 16:16.
|
|
06.09.2014, 22:27
|
|
Быдлокодер;)
|
|
Регистрация: 19.11.2010
Сообщений: 4,338
|
|
Я как раз сейчас этим занимаюсь в рамках Collection 5.2 (в сообщение по ссылке есть ссылка на демо видео, где создано 50 потоков с разными приоритетами, каждый из которых считает 1кк итераций), где потоки реализуются с помощью прерываний (yield) функций и планировщика, т.е. модель такая же как и в потоках на одноядерных процах.
Цитата:
|
Современное решение: web worker.
|
К сожалению решение довольно однобокое, т.к. с одной стороны - это не JS, а некоторая приблуда браузера, а также очень много ограничений (в том числе на количество создаваемых потоков в рамках домена), да и сама операция создания довольно дорогая.
Последний раз редактировалось kobezzza, 06.09.2014 в 22:31.
|
|
06.09.2014, 22:38
|
|
Тлен
|
|
Регистрация: 02.01.2010
Сообщений: 6,588
|
|
Сообщение от kobezzza
|
К сожалению решение довольно однобокое
|
Справедливо, тем не менее большинство обычных проблем решает.
То что делаешь ты - крутотень, но весьма специфическая.)
__________________
29375, 35
|
|
06.09.2014, 22:44
|
|
Быдлокодер;)
|
|
Регистрация: 19.11.2010
Сообщений: 4,338
|
|
Сообщение от Aetae
|
То что делаешь ты - крутотень, но весьма специфическая.)
|
На самом деле нет, как сделаю релиз, то сможешь убедится: я сделаю наглядную демку, в которой можно будет пощупать и увидеть, что всё супер просто.
// Простая синхронная итерация
$C([...]).forEach(function () {
...
});
// Итерация в потоке
$C([...]).forEach(function () {
...
}, {thread: true});
Главный плюс таких потоков, что по сути, мы остаёмся в главном потоке и у нас спокойный доступ к DOM, переменным замыкания и т.д. хотя с другой стороны это и минус - т.к. можно выстрелить себе в ногу.
К сожалению самый главный недостаток этого подхода - это необходимость поддержки генераторов, а она есть только в Хроме и ФФ, но обещали вкрутить в ИЕ12, а про Сафари я даже не знаю, надо будет посмотреть, но в ноде я уже планирую полноценное внедрение этой технологии.
Последний раз редактировалось kobezzza, 06.09.2014 в 22:59.
|
|
07.09.2014, 20:05
|
Новичок на форуме
|
|
Регистрация: 06.09.2014
Сообщений: 2
|
|
Сообщение от Aetae
|
По старинке: дробить вычисления setTimeout'ами.
|
Вот именно! Очень хотелось бы без всяких премудростей setTimeout'ами добиться того, чтобы браузер не зависал.
Но куда вставлять этот setTimeout, если функция, вызывающая зависание браузера, рекурсивная?
function recfrugal(k)
{
var i;
var j;
var t;
var q;
if (k == 82)
{
u++;
for (i = 1; i <= 81; i++) z[i][u] = s[i]
}
if ((k <= 81) && (u < 10))
{
if ((w[k] == 0) || (w[k] == 1)) recfrugal(k+1);
if (w[k] > 1)
{
for (t = 1; t <= w[k]; t++)
{
q = true;
for (j = 1; j <= 20; j++) if (b[k][t] == s[m[k][j]]) q = false;
if (q == true)
{
s[k] = b[k][t];
c++;
recfrugal(k+1);
}
}
s[k] = 0;
c++;
}
}
}
Если заменить рекурсивный вызов recfrugal(k+1); вот так:
setTimeout(function() { recfrugal(k+1) }, 1000);
то ничего не получается, так как она просто будет через него перескакивать, корректного результата не получится.
|
|
07.09.2014, 20:24
|
|
Тлен
|
|
Регистрация: 02.01.2010
Сообщений: 6,588
|
|
Переписать рекурсию на циклы.
__________________
29375, 35
|
|
12.09.2014, 16:53
|
|
Быдлокодер;)
|
|
Регистрация: 19.11.2010
Сообщений: 4,338
|
|
|
|
|
|