How to Use setTimeout in a for…loop

后端 未结 4 1114
北恋
北恋 2021-01-16 11:35

What I want is this (news ticker type functionality):

  1. Get a list of li\'s from a ul tag
  2. Loop through all the li\'s and get the text
  3. display t
相关标签:
4条回答
  • 2021-01-16 11:51

    As Greg mentioned the problem is with the closure only evaluating once. Nobody posted a solution for this so here is one. This uses adding a function that generates the callback function each time:

    Add:

    function getShowTextCallback(text) {
        return function(){showText(text)}
    }
    

    Then use it in loop like this:

    for(var x=0; x < li.length; x++){
        var li_text = li[x].childNodes[0].nodeValue;
        setTimeout(getShowTextCallback(li_text), 1000);
    }
    
    0 讨论(0)
  • 2021-01-16 12:04

    Change this:

    for(var x=0; x < li.length; x++){
        var li_text = li[x].childNodes[0].nodeValue;
        setTimeout(function(){showText(li_text)}, 1000);
    }
    

    To:

    for(var x=0; x < li.length; x++) (function() {
        var li_text = li[x].childNodes[0].nodeValue;
        setTimeout(function(){showText(li_text)}, x * 1000);
    })()
    
    0 讨论(0)
  • 2021-01-16 12:08

    How about we just move some of the code around a bit... take out the closure issue...

    var ul = document.getElementById('post_list');
    var li = ul.getElementsByTagName('li');
    
    for (var x = 0, xl = li.length; x < xl; x++) {
        var li_text = li[x].innerText || li[x].textContent; // does IE support textContent??
        showText(li_text, x * 1000);
    }
    
    function showText(text, delay) {
        setTimeout(function() {
            console.log(text);
        }, delay);
    }
    

    I assume the delay you want to be sequential (hence the loop). Because setTimeout is not blocking you will need to have a callback on the function to invoke the next setTimeout or you will need to specifically increment each function call with a new delay.

    0 讨论(0)
  • 2021-01-16 12:11

    The reason this is happening is because of closures. The for loop block has closures around it, so when you reference 'li_text' it was always equal the last value that li_text was set to. The for loop does not create a separate closure for each iteration through the loop.

    0 讨论(0)
提交回复
热议问题