2015-04-25 4 views
0

Я читал о setTimeout и других таких таймерах. Но мне интересно, если это возможно, чтобы работать до пользовательской функции, так что все, что вам нужно будет сделать, это что-то вроде этого:Создание функции «задержки» в JS?

//code 
delay(time); 
//more code 

Возможно ли это?

UPDATE: Хорошо, я как бы понял. Так что, если это не является разумным возможным, как бы вы хотели бы отложить цикл ПОСЛЕ первого раза. Я хочу, чтобы он запускался сразу же после выполнения, но потом они задерживаются на каждой итерации.

Новое ОБНОВЛЕНИЕ: Я думаю, что, поскольку моя первоначальная мысль провалилась, вам может быть проще показать вам код, который у меня есть.

function autoFarm (clickEvent){ 

var farmTargets = [ 
      "6_300_1", 
      "6_300_3", 
      "6_300_4", 
      "6_300_5", 
      "6_300_7"]; 


setTimeout(function() { 
$.each (farmTargets, function(index, target){  
    var extraData = '{"end_pos":"' + target + '","purpose":0,"upshift":1,"bring_res":{"0":0,"2":0,"1":0},"bring_ship":{"1":25,"11":0},"rate":100,"start_pos":"6_300_2"}'; 

var finalData = baseDataDora + extraData + "&type=1"; 

setTimeout(function(){ 
    for (i = 0; i < farmTargets.length; i++){ 
     postRequest(sendFleetURL + getSign(extraData). finalData, function(json){    
     });    
    }  
}, 15000); 
});//End each loop 
}, 1320000);  
}//End autoFarm 

В принципе, он должен выполнить немедленно и запустить цикл цикла 5 раз на первом элементе массива на расстоянии 15 секунд. Затем через 22 минуты перейдите к следующему набору и повторите для всего массива.

+0

Возможно с генераторами. – elclanrs

+0

http://stackoverflow.com/questions/951021/what-do-i-do-if-i-want-a-javascript-version-of-sleep – drs9222

+0

Я не знаком с генераторами. –

ответ

0

Это невозможно из-за способа работы однопоточных циклов событий. Если бы эта функция существовала, это заставило бы весь поток пользовательского интерфейса замораживаться до тех пор, пока не будет выполнена задержка. setTimeout(cb, delay) - ближайший объект, который планирует выполнение функции не ранее, чем задержка, и в конце цикла цикла событий.

Обновление: Прежде чем кто-нибудь позвонит мне, да, теоретически вы можете спроектировать функцию задержки, которая замерзает все на месте в течение установленного промежутка времени. Однако нет разумного оправдания для этого.

Для вашего второго вопроса:

function hello() { 
    console.log('hello'); 
} 

// execute immediately 
hello(); 

// then every 5 seconds 
setInterval(hello, 5000); 
+0

Хорошо. Один вопрос у меня есть. У меня есть цикл for внутри каждого цикла. Если я положил функцию setTimeout на нижнюю часть, чтобы снова вызвать функцию задержка, эти циклы удерживают свое место так, чтобы говорить? –

+0

Если я правильно вас понимаю, нет. Они будут выполняться по порядку, но если ваш цикл зацикливается 1000 раз, и вы сделали 1000 setTimeout (fn, 1000), через одну секунду вызовы 1000 функций будут происходить один за другим. – brian

0

Как написано, нет, это невозможно.

Если вместо этого вы должны использовать очередь, задержки таким образом тривиальны.

Функции jQuery's .queue() и .delay() являются хорошим примером того, как это работает, поэтому я буду использовать их в качестве примера, однако общая точка обозначает любую библиотеку очередей.

Вместо:

//code 
delay(time) 
//more code 

С очередью, вы бы написать:

$('...') //some selector to act on for jQuery 
.queue(function (next) { 
    //code 

    //Indicate that the queued call is finished. 
    next(); 
    //This allows async code to be executed in the queue, 
    //such as ajax and animations 
}) 
.delay(time) 
.queue(function (next) { 
    //more code 
    next(); 
}); 

Теперь, даже если игнорировать строки, используемые для комментариев, вы можете сказать, что есть немного больше для достижения желаемого поведения. Я не чувствую, что это чрезмерно, потому что я считаю, что относительно легко читать:

  1. очереди что-то должно произойти
  2. ждать в течение некоторого количества миллисекунд
  3. очереди что-то еще должно произойти
1

Вы можете добиться чего-то в этом направлении с помощью генераторов. Идея заключается в том, что стиль продолжения прохождения (callback hell) может быть сплющен.Генератор использует yield ключевое слово, чтобы приостановить функцию, пока обратный вызов не возобновляет его, вызвав next метод:

var async = function(gen) { 
    var g = gen() 
    function next(x) { 
    var cur = g.next(x) 
    if (cur.done) { 
     return cur.value 
    } 
    cur.value(next) 
    } 
    next() 
} 

var delay = function(time) { 
    return function(f) { 
    setTimeout(f, time) 
    } 
} 

async(function*() { 
    console.log('before') 
    yield delay(1000) // waits one second 
    console.log('middle') 
    yield delay(1000) // waits one second 
    console.log('after') 
}) 

В КПСЕ было бы что-то вроде следующего содержания:

console.log('before') 
setTimeout(function() { 
    console.log('middle') 
    setTimeout(function() { 
    console.log('after') 
    }, 1000) 
}, 1000) 

Это работает в Chrome, Firefox и iojs сегодня.

+0

+1. Другой вариант - синтаксис async/wait, предложенный для ES7 (см. Http://pouchdb.com/2015/03/05/taming-the-async-beast-with-es7.html), который может быть достигнут сегодня с [Babel] (http://babeljs.io/docs/usage/transformers/other/async-to-generator/) –

Смежные вопросы