【问题标题】:How to process asynchronous functions in a loop sequentially如何顺序处理循环中的异步函数
【发布时间】:2019-01-15 15:11:20
【问题描述】:

我正在尝试更改文本,以便它们一次出现一个,几乎以连续的方式出现。

columns.forEach((x) => {
    setTimeout(() => {
        x.style.color="red"
    }, 2500)

})

但是,这只是将它们全部延迟 2500 毫秒,然后在 2500 毫秒后,它们同时发生变化。

【问题讨论】:

  • (x) 替换为(x, i)(即索引)并将延迟设置为2500 + i * 500
  • 队列会好很多
  • 我可能也会使用队列,但老实说,这在内部本质上是一个队列。

标签: javascript


【解决方案1】:

.forEach() 方法将索引值作为第二个参数传递。您可以将其乘以某个常数以分散计时器:

columns.forEach((x, index) => {
    setTimeout(() => {
        x.style.color="red";
    }, 2500 + index * 500);

});

【讨论】:

  • 延迟不应该是(index + 1) * 2500吗?
  • @ibrahimmahrir 为什么你认为 OP 想要 2500 之间?
  • @ChrisG OP 在他的setTimeout 中使用2500
  • 它可以是任何 OP 想要的;这只是一个例子。
【解决方案2】:

Promisesasync / await,让这样的操作看起来更加自然,并且易于遵循/调试。

const columns = document.querySelectorAll("td");

const sleep = (ms) => new Promise(r => setTimeout(r, ms));

async function run() {
  for (const c of columns) {
    await sleep(2500);
    c.style.color = 'red';
  }
}

run();
td {
  border: 1px solid black;
  padding: 5px;
  margin: 3px;
}
<table>
  <tr>
    <td>1</td>
    <td>2</td>
    <td>3</td>
    <td>4</td>
    <td>5</td>
    <td>6</td>
    <td>7</td>
  </tr>
</table>

【讨论】:

    【解决方案3】:

    这样的事情怎么样?

    # cat forEachAsync.js
    function forEachAsync(array, fun, cb) {
            var index = 0;
            if (index == array.length) {
                    cb(null);
                    return;
            }
    
            var next = function () {
                    fun(array[index], function(err) {
                            if (err) {
                                    cb(err);
                                    return;
                            }
                            index++;
                            if (index < array.length) {
                                    setImmediate(next);
                                    return;
                            }
    
                            //We are done
                            cb(null);
                    });
            };
            next();
    }
    
    var columns = [1,2,3,4,5]
    forEachAsync(columns, function(e, cb) {
            console.log('changing column: ' + e);
            // let them know we have done with this
            // entry so we can start processin the
            // next entry.
            cb();
    }, function(err) {
            if (err) {
                    console.log('Failed in the process' + e.toString());
                    return;
            }
            console.log('## done ##');
    });
    # node forEachAsync.js
    changing column: 1
    changing column: 2
    changing column: 3
    changing column: 4
    changing column: 5
    ## done ##
    #
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-01-18
      • 2019-04-17
      • 2012-04-04
      • 2020-03-07
      • 1970-01-01
      • 2012-12-27
      • 2016-10-25
      相关资源
      最近更新 更多