Multithreading в Javascript (как реализовать)

Модератор: Модераторы разделов

frp
Сообщения: 1445
ОС: Debian Squeeze

Multithreading в Javascript

Сообщение frp »

Как реализовать потоки в Javascript (можно сделать эмуляцию)?

Обратная совместимость с Internet Explorer 6 не нужна.
Спасибо сказали:
Аватара пользователя
serzh-z
Бывший модератор
Сообщения: 8259
Статус: Маньяк
ОС: Arch, Fedora, Ubuntu

Re: Multithreading в Javascript

Сообщение serzh-z »

frp писал(а):
10.07.2009 15:39
Как реализовать потоки в Javascript (можно сделать эмуляцию)?
Никак... Коллбеки уже не катят?
Спасибо сказали:
frp
Сообщения: 1445
ОС: Debian Squeeze

Re: Multithreading в Javascript

Сообщение frp »

Нужно, чтобы во время выполнения длительной операции броузер не вис и отображал прогрессбар.

Не обязательно, чтобы было по настоящему много потоков - можно эмулировать (так делали когда-то на 8086 в MSDOS - на прерывание таймера вешали планировщик, который переключал задачи, в Javascript возникает одна проблема - событие таймера не прерывает выполнение скрипта, а ставиться в очередь).
Еще раз повторяю - совместимость с Internet Explorer 6 не нужна.
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Multithreading в Javascript

Сообщение NickLion »

Какого рода эта длительная операция? Возможно получится сделать что-то вроде setTimeout( <действия>, <малое время> )...
Спасибо сказали:
Аватара пользователя
Portnov
Модератор
Сообщения: 1786
Статус: Матёрый линуксоид
ОС: Debian testing/unstable

Re: Multithreading в Javascript

Сообщение Portnov »

Афаик, для прогресс-баров обычно делают как сказал NickLion. Т.е. скажем каждые N миллисекунд выясняем, на сколько процентов завершилась операция и соответственно обновляем прогресс-бар.
Работа: Ubuntu 9.10
Дом: Debian testing/unstable и на всякий случай winxp в virtualbox.
Для разнообразия: моя домашняя страница -http://iportnov.ru
Спасибо сказали:
frp
Сообщения: 1445
ОС: Debian Squeeze

Re: Multithreading в Javascript

Сообщение frp »

Portnov писал(а):
10.07.2009 21:35
Афаик, для прогресс-баров обычно делают как сказал NickLion. Т.е. скажем каждые N миллисекунд выясняем, на сколько процентов завершилась операция и соответственно обновляем прогресс-бар.

А как при этом сделать, чтобы броузер не висел? У меня если долго выполняется скрипт, то броузер почти виснет.

Нагуглил такую доку - http://www.neilmix.com/2007/02/07/threadin...-javascript-17/ Кто может объяснить как оно действует? Какими броузерами кроме Firefox поддерживается?
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Multithreading в Javascript

Сообщение NickLion »

frp, там идет завязка именно на Firefox, абсолютно нестандартные вещи. Вот пример кода, который выполняется продолжительное время, и браузер при этом не висит. В чем теоретическая сложность переделать Ваш код по образу?

Код: Выделить всё

<HTML>
<HEAD><TITLE>Counter</TITLE></HEAD>
<BODY>
<DIV id="cnt"></DIV>

<script type="text/javascript">
function ff() {
    var x = 0;
    var me = setInterval( function() {
        x++;
        document.getElementById( "cnt" ).innerHTML = x;
        if( x == 1000 ) clearInterval( me );
    }, 0 );
}
ff();
</SCRIPT>

</BODY>
</HTML>
Спасибо сказали:
frp
Сообщения: 1445
ОС: Debian Squeeze

Re: Multithreading в Javascript

Сообщение frp »

NickLion писал(а):
11.07.2009 11:55
Вот пример кода, который выполняется продолжительное время, и браузер при этом не висит. В чем теоретическая сложность переделать Ваш код по образу?

Переделаю.

А вообще вы подкинули идею, как сделать нормальный multithreading.
А в Javascript есть аналог goto? Можно и if-ами, но сложно.
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Multithreading в Javascript

Сообщение NickLion »

Аналога goto нет. Можно по меткам из цикла выходить:

Код: Выделить всё

label: for/while(...){
    ...
    for/while(...) {
        ...
        break/continue label;
    }
    ...
}

Можно "почти" goto сделать так:

Код: Выделить всё

do {
    ...
    if( something ) break;
    ...
    if( something_else ) break;
    ...
} while( 0 );

Если нужен goto назад то применяем технику с циклом и continue. Если вперед, то с циклом и break. Ну а если if'ом заменить не очень сложно, то if :)
Спасибо сказали:
frp
Сообщения: 1445
ОС: Debian Squeeze

Re: Multithreading в Javascript

Сообщение frp »

NickLion писал(а):
11.07.2009 16:39
Аналога goto нет. Можно по меткам из цикла выходить:
Код
label: for/while(...){
...
for/while(...) {
...
break/continue label;
}
...
}

А можно пример кода, так делающий? А то у меня Firefox постоянно говорит, что Label not found.

UPD. Ошибка только если метка после break или continue. Как быть?
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Multithreading в Javascript

Сообщение NickLion »

Код: Выделить всё

<HTML>
<HEAD>
<TITLE>Ugly GOTO emulators</TITLE>
</HEAD>
<BODY>

<script type="text/javascript">
function ff() {
    //backward goto emulation
    alert( "Now we show backward goto emulation" );
lbl1:
    while( 1 ) {
        var r = confirm( "Goto backward after 4?" );
        // another loop
        for( var i = 0; i < 10; i++ ) {
            if( ( i >= 5 ) && r )
                continue lbl1;
            else
                alert( i );
        }
        break;
    }
    //forward goto emulation
    alert( "Now we show forward goto emulation" );
lbl2:
    while( 1 ) {
        var r = confirm( "Goto forward after 4?" );
        // another loop
        for( var i = 0; i < 10; i++ ) {
            if( ( i >= 5 ) && r )
                break lbl2;
            else
                alert( i );
        }
        break;
    }
    alert( "Goodbye! Have a nice day!" );
}
ff();
</SCRIPT>

</BODY>
</HTML>
Спасибо сказали:
frp
Сообщения: 1445
ОС: Debian Squeeze

Re: Multithreading в Javascript

Сообщение frp »

Спасибо.
Сделал некоторое подобие multithreading. Вот так сделал планировщик:

Код: Выделить всё

function scheduler()
{
    var i;
    for(i=0;i<threads.length;i++)
    {
        if(statuses[i]==status_running)
            statuses[i]=threads[i](locals[i]);
    }
    setTimeout(scheduler,0);
}

Есть один очень неудобный момент - для нормальной работы этой схемы функции, эмулирующие потоки, должны очень часто делать return status_running. Неудобство в том, что функция после следующего вызова должна начать выполнение с того места, где оно остановилось (для этого и нужен goto (в Firefox ситуация лучше - есть yield)).

PS. Multithreading в MSDOS и то проще реализовать и функции не должны даже об этом знать.

UPD. Нашел скрипт, который реализует нормальный goto назад с использованием continue: http://www.summerofgoto.com/
Спасибо сказали: