2011-02-01 3 views
2

Я знаю, что существует множество методов, таких как setTimeout, но я просто хочу РЕАЛЬНЫЙ.Как сделать РЕАЛЬНЫЙ сон() в JavaScript?

Я использую JavaScript для написания компилятора, и мне нужно выяснить способ реализации функции sleep(). Я знаю, что это багги, это не то, что я хочу.

Спасибо.

+0

Реально, вы имеете в виду? Что вы проектируете? –

+5

Зачем вам нужно спать() при компиляции кода? – Metal

+0

Это плохая идея, если вы планируете запускать этот код в браузере, и ваша цель - не замораживать пользовательский интерфейс. – ide

ответ

5

Из приведенных выше ответов я собираю, что вы хотите функцию сна, которая не замерзает браузер и не использует setTimeout.

Удачи вам в этом, javascript однопоточный.Это не возможно

+0

Однопоточный javascript === Невозможно скрыть поток без блокировки. – Raynos

+0

Знаете ли вы что-то вроде Concurrent.Thread? –

+0

@Xhacker, он только что сказал, что javscript является однопоточным, что означает, что у него нет абсолютно никакой концепции потоков или параллелизма вообще. : D –

0

Если вы хотите просто вызвать функцию в X миллисекундах, вы можете использовать setTimeout, но вы это знали.

Вы можете взломать вещи вместе с использованием даты и getTime.

function sleep(milliseconds) { 
    var now = new Date(); 
    var exitTime = now.getTime() + milliseconds; 
    while (true) { 
     now = new Date(); 
     if (now.getTime() > exitTime) 
     return; 
    } 
} 

stolen from here

Однако вы полностью заморозить текущий поток для возможного длительного периода времени. Я думаю, вы в основном остановите все действия javscript на странице за X миллисекунды, что будет очень раздражает, если время больше 300 мс.

there's some pretty good analysis of javscript sleep methods here.

Если вы дадите нам немного больше контекста, мы, вероятно, может быть более полезным. Сон обычно используется в многопоточных сценариях на других языках, и именно поэтому он был исключен из javascript. Какие функции вам нужны в вашем компиляторе? : D

+0

Спасибо, но это не то, что я хочу ... Это горелка для процессора. –

+0

cpu hog [больше символов] –

+0

@Xhacker, что вам нужно? На данный момент все, что мы можем сделать, это догадываться. Зачем вам спать? Каковы ваши требования? : D –

4

Вы не можете, по крайней мере, в большинстве реализаций браузера. Вам придется заставить ваш компилятор обойти это. StratifiedJS делает что-то подобное.

Я добавлю еще несколько деталей. Это, очевидно, это не самый лучший способ реализации функции сна, но так как вы сказали, что вы делаете простой язык рисования, я просто идти с этим:

Представьте, что вы есть некоторый код, как это:

drawLine(1, 2, 3, 4); 
sleep(1000); 
drawLine(5, 6, 7, 8); 

это может быть превращена в этот разбивая все sleep S:

var pieces; 
function advance() { 
    pieces.shift()(); 
} 
pieces=[ 
    function() { 
     drawLine(1, 2, 3, 4); 
     setTimeout(advance, 1000); 
    }, 
    function() { 
     drawLine(5, 6, 7, 8); 
    } 
]; 
advance(); 

Или, если ваш язык является более сложным, чем это, вы могли бы сделать это с большей сложностью для компилятора (это очевидное решение):

drawLine(1, 2, 3, 4); 
setTimeout(function() { 
    drawLine(5, 6, 7, 8); 
}, 1000); 

Опять же, это может быть неприменимо, если ваш язык становится очень сложным, но может оказаться полезным в качестве отправной точки.

+0

Значит, вы имеете в виду, что я не могу реализовать функцию sleep()? –

+1

@Xhacker Liu: Это то, что я говорю. Однако вы можете заставить ваш компилятор преобразовать синхронный код в асинхронный код, поэтому избегайте проблемы. – icktoofay

+0

Почему все еще думают, что каждая программа Javascript работает в браузере? :-) – paxdiablo

2

Звуки для меня, как вы хотите, чтобы принимать блок петлю

while(condition) { 
    // do something 
    sleep(x); 
} 

и превратить его в

function foo(values) { 
    if(condition) { 
     // do something 
     setTimeout(function() { 
      foo(values); 
     }, x); 
    } 
} 
foo(someValue); 

Также вы можете взять цикл

for (var i = 0; i < n; i++) { 
    // do something 
    sleep(x); 
} 

и превратить его в

function foo(i) { 
    // do something 
    i++; 
    if (i < n) { 
     setTimeout(function() { 
      foo(i); 
     }, x); 
    } 
} 
foo(0); 

В основном превратите ваши циклы в рекурсивные вызовы, а затем замените свои сны асинхронными рекурсивными вызовами.

В цикле вам необходимо физически блокировать, чтобы замедлить шаг. В рекурсии вы можете отложить вызов к следующей рекурсивной функции.

1

только реальный и разумный способ реализации sleep() в JavaScript (по крайней мере, в среде браузера) заключается в использовании setTimeout. Просто обработайте свои скомпилированные инструкции один за другим, а затем сделайте перерыв, когда вы столкнетесь с инструкцией о спящем режиме:

function resume() { 
    while (instructions.length) { 
     var instruction = instructions.shift(); 

     switch (instruction.opcode) { 
     case "foo": 
      doFoo(instruction.operands); 
      break; 
     case "bar": 
      doBar(instruction.operands); 
      break; 
     case "sleep": 
      doSleep(instruction.operands); 
      return; // pause running 
     } 
    } 
} 

function doSleep(operands) { 
    setTimeout(resume, operands[0]); 
} 

var instructions = compile(source); 
resume(); 
Смежные вопросы