Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #11 (permalink)  
Старый 26.08.2008, 15:00
Интересующийся
Отправить личное сообщение для Autosof Посмотреть профиль Найти все сообщения от Autosof
 
Регистрация: 23.08.2008
Сообщений: 20

Сообщение от Kolyaj Посмотреть сообщение
Ну если по теме: в JavaScript функции -- объекты первого типа
Это явно из какой-то теории. По сему вопрос - какие типы ещё бывают и чем отличаются (кроме номеров)? Ну это так, из спортивного интереса.

Сообщение от Kolyaj Посмотреть сообщение
... открывает такие возможности написания простого и лаконичного кода, который ObjectPascal'ю даже не снился.
Цены бы Javascript не было, если бы можно было реализовать то с чего тема начата была...
А так остается только приспосабливаться к особенностям языка.
Ответить с цитированием
  #12 (permalink)  
Старый 02.08.2011, 06:55
Профессор
Отправить личное сообщение для Почемучкин Посмотреть профиль Найти все сообщения от Почемучкин
 
Регистрация: 11.05.2011
Сообщений: 241

Мнэээ... наткнулся тут на эту тему. И чисто для справки тем кто как и я будут читать архив, вставлю, что я пока в JavaScript не большой специалист, но в Delphi тоже можно передавать функции как параметры - по ссылке, и возвращать как результат работы. Более того, есть даже возможность описывать типы как функции. Например можно сделать массив или список функций.
И еще - почитал тут в инете, что вроде можно в JavaScript использовать window.postMessage, так что какая-никакая обработка сообщений в нем есть и соответственно это касается вопроса топикстартера. Он не про многопоточность спрашивал, а про передачу управления в очередь обработки сообщений, пока происходит ожидание - заметьте, что это именно в однопоточном приложении. И насколько я понял - если пользоваться очередью сообщений, написав свой ProcessMessages, то только в IE скрипт будет блокироваться, а в других браузерах будет работать асинхронно.

Последний раз редактировалось Почемучкин, 02.08.2011 в 06:58.
Ответить с цитированием
  #13 (permalink)  
Старый 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?
Ответить с цитированием
  #14 (permalink)  
Старый 06.09.2014, 16:09
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,501

JS однопоточный язык. Нет в нём изначально никаких "других" процессов. Остановка - есть остановка всего на странице.

Современное решение: web worker. Он создаёт отдельный поток из отдельного скрипта, что общается с основным потоком сообщениями.
По старинке: дробить вычисления setTimeout'ами.
__________________
29375, 35

Последний раз редактировалось Aetae, 06.09.2014 в 16:16.
Ответить с цитированием
  #15 (permalink)  
Старый 06.09.2014, 22:27
Аватар для kobezzza
Быдлокодер;)
Отправить личное сообщение для kobezzza Посмотреть профиль Найти все сообщения от kobezzza
 
Регистрация: 19.11.2010
Сообщений: 4,338

Я как раз сейчас этим занимаюсь в рамках Collection 5.2 (в сообщение по ссылке есть ссылка на демо видео, где создано 50 потоков с разными приоритетами, каждый из которых считает 1кк итераций), где потоки реализуются с помощью прерываний (yield) функций и планировщика, т.е. модель такая же как и в потоках на одноядерных процах.

Цитата:
Современное решение: web worker.
К сожалению решение довольно однобокое, т.к. с одной стороны - это не JS, а некоторая приблуда браузера, а также очень много ограничений (в том числе на количество создаваемых потоков в рамках домена), да и сама операция создания довольно дорогая.
__________________
kobezzza
code monkey

Последний раз редактировалось kobezzza, 06.09.2014 в 22:31.
Ответить с цитированием
  #16 (permalink)  
Старый 06.09.2014, 22:38
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,501

Сообщение от kobezzza Посмотреть сообщение
К сожалению решение довольно однобокое
Справедливо, тем не менее большинство обычных проблем решает.
То что делаешь ты - крутотень, но весьма специфическая.)
__________________
29375, 35
Ответить с цитированием
  #17 (permalink)  
Старый 06.09.2014, 22:44
Аватар для kobezzza
Быдлокодер;)
Отправить личное сообщение для kobezzza Посмотреть профиль Найти все сообщения от kobezzza
 
Регистрация: 19.11.2010
Сообщений: 4,338

Сообщение от Aetae Посмотреть сообщение
То что делаешь ты - крутотень, но весьма специфическая.)
На самом деле нет, как сделаю релиз, то сможешь убедится: я сделаю наглядную демку, в которой можно будет пощупать и увидеть, что всё супер просто.

// Простая синхронная итерация
$C([...]).forEach(function () {
    ...
});

// Итерация в потоке
$C([...]).forEach(function () {
    ...
}, {thread: true});


Главный плюс таких потоков, что по сути, мы остаёмся в главном потоке и у нас спокойный доступ к DOM, переменным замыкания и т.д. хотя с другой стороны это и минус - т.к. можно выстрелить себе в ногу.

К сожалению самый главный недостаток этого подхода - это необходимость поддержки генераторов, а она есть только в Хроме и ФФ, но обещали вкрутить в ИЕ12, а про Сафари я даже не знаю, надо будет посмотреть, но в ноде я уже планирую полноценное внедрение этой технологии.
__________________
kobezzza
code monkey

Последний раз редактировалось kobezzza, 06.09.2014 в 22:59.
Ответить с цитированием
  #18 (permalink)  
Старый 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);

то ничего не получается, так как она просто будет через него перескакивать, корректного результата не получится.
Ответить с цитированием
  #19 (permalink)  
Старый 07.09.2014, 20:24
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,501

Переписать рекурсию на циклы.
__________________
29375, 35
Ответить с цитированием
  #20 (permalink)  
Старый 12.09.2014, 16:53
Аватар для kobezzza
Быдлокодер;)
Отправить личное сообщение для kobezzza Посмотреть профиль Найти все сообщения от kobezzza
 
Регистрация: 19.11.2010
Сообщений: 4,338

Оставлю тут ссылку: реализация потоков в Collection 5.2
__________________
kobezzza
code monkey
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск