2013-11-13 2 views
0

Следующий код запрашивает json-данные из URL-адреса. После того, как он имеет эти данные, он запускает функцию .each для каждого элемента в json-данных. Для примера я уменьшил функцию .each, просто выполнив document.write с каждым значением из json и предупредив «закончен» после его окончания.Включить setTimeout В jQuery .each

Если я удалю setTimeout, тогда код работает так, как должен, сначала заканчивая все команды .each, а затем завершая предупреждение. Однако, с помощью setTimeout, он предупреждает о завершении до того, как он выполнит все команды .each.

У меня сама задержка работает отлично, однако код ПОСЛЕ первоначальной задержки выполняется немедленно, не дожидаясь выполнения всех команд .each. Вот код:

$.ajax({ 
      type: "GET", 
      url: 'url to json data', 
      dataType: "json", 
      success: function(data) { 
      var time = 10; 
       $.each(data, function(key, val) { 
       setTimeout(function() { 
       document.write(val.term); 
        return; 
       }, time); time += 10; 
       }); 
      alert('finished'); 
      }, 
      error: function() {} 
     }) 

Как я могу держать задержку во время прохода через команду .each и только тогда, когда она будет закончена перебор всех команд .each, бдительная 'закончила?

+3

«с SetTimeout, она оповещения закончена прежде, чем она выполняет все команды .each». Да, это то, что делает 'setTimeout'. Он запускает заданную функцию после X ms. Это * асинхронно *. Остальная часть вашего кода запускается, затем 'setTimeout' запускается через некоторое время. –

+0

Могу ли я спросить, почему вы используете 'document.write()'? Это редко нужно использовать ... – Dom

+1

... и почему вы хотите использовать setTimeout в этом конкретном случае использования? – meavo

ответ

3

Что вы можете сделать, это использовать отложенные jQuery здесь. Используйте обещание, а затем вызовите обратный вызов, когда все будет сделано.

непроверенная, но вы можете сделать что-то вроде этого:

$.ajax({ 
    type: "GET", 
    url: 'url to json data', 
    dataType: "json", 
    success: function(data) { 
     var time = 10, 
      timeouts = []; 
     $.each(data, function(key, val) { 
      var def = new $.Deferred; 
      timeouts.push(def); 

      setTimeout(function() { 
       console.log(val.term); 
       def.resolve(); 
      }, time); 
      time += 10; 
     }); 

     $.when.apply($, timeouts).done(function(){ 
      alert('finished'); 
     }); 
    }, 
    error: function() {} 
}) 
+0

Да, это хорошо работает 'http: // jsfiddle.net/4t7pH /' – melc

+0

Ничего себе ... это прекрасно работает. Я ценю это, спасибо. То, что вы использовали для выполнения этой работы, я даже не знал, что существует ... Я смог включить то, что вы предоставили, в фактический код, который я использую, и он работает на 100% отлично. Еще раз спасибо. – Learning

+0

Добро пожаловать! Рад, что я мог бы помочь :-D –

1

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

$.ajax({ 
     type: "GET", 
     url: 'url to json data', 
     dataType: "json", 
     success: function(data) { 
     var time = 10; 
     var t=setTimeout(function(){alert('finished');} , 20); 
      $.each(data, function(key, val) { 
      setTimeout(function() { 
      //document.write(val.term); 
       clearTimeout(t); 
       t=setTimeout(function(){alert('finished');} , 20); 
       return; 
      }, time); time += 10; 
      }); 
     }, 
     error: function() {} 
    }) 
+0

Вам понадобится 'clearTimeout (t)' где-то здесь. Повторное присвоение 't' не очистит старый тайм-аут (ы), они все равно будут работать. –

+0

Дох! Благодарю. Обновлено. – Moob

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