首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >函数完成后才再次运行函数。

函数完成后才再次运行函数。
EN

Stack Overflow用户
提问于 2022-10-29 21:00:28
回答 3查看 45关注 0票数 0

我正试图制作一个程序,将文本添加到网页中,如下所示:

代码语言:javascript
复制
Hello
Morning
Morning
Morning
Morning
Evening

应该有:

  1. 5秒延迟在“你好”和第一个“早晨”之间,
  2. 5秒延迟在每个“早晨”之间,
  3. 6秒延迟在最后一个“早晨”和“晚上好”之间。

这是我到目前为止得到的整个HTML和JavaScript。

代码语言:javascript
复制
function notify(msg, loops, taskTime) {
  var ul = document.getElementById("notifications");
  for (let i = 0; i < loops; i++) {
    (function(i) {
      window.setTimeout(function() {
        var li = document.createElement("li")
        li.appendChild(document.createTextNode(`${msg}`));
        ul.appendChild(li)
      }, taskTime * i)
    }(i))
  }
}

notify('Hello', 1, 5000)
notify('Morning', 4, 5000)
notify('Evening', 1, 6000)
代码语言:javascript
复制
<div>
  <ul id="notifications" style="list-style-type:none;margin-left:10%;"></ul>
</div>

我的问题是,在加载网页时,输出是:

代码语言:javascript
复制
Hello
Morning
Evening
Morning
Morning
Morning

如何确保函数按我希望的顺序运行,而不是按照混合输出的顺序运行?前3项输出也立即出现,而不是延迟。我该怎么避免呢?

EN

回答 3

Stack Overflow用户

发布于 2022-10-29 21:12:42

乘以毫秒数,以便后面的setTimeout分配正确的时间。此外,您还将taskTimei相乘,这两个值始终为0。我用i + 1代替了i + 1

只需尝试以下JavaScript代码即可(它有效):

代码语言:javascript
复制
function notify(msg, loops, taskTime) {
  var ul = document.getElementById("notifications");
  for (let i = 0; i < loops; i++) {
    (function (i) {
      window.setTimeout(function () {
        var li = document.createElement("li")
        li.appendChild(document.createTextNode(`${msg}`));
        ul.appendChild(li)
      }, taskTime * (i + 1))
    }(i))
  }
}

notify('Hello', 1, 5000)
notify('Morning', 4, 5000 * 2)
notify('Evening', 1, 6000 + 5000 * 6)
票数 0
EN

Stack Overflow用户

发布于 2022-10-29 21:25:04

根据Mike的评论:

代码语言:javascript
复制
tasks = [
    {message: 'Hello', delay: 5000},
    {message: 'Morning', delay: 5000},
    {message: 'Morning', delay: 5000},
    {message: 'Morning', delay: 5000},
    {message: 'Morning', delay: 5000},
    {message: 'Evening', delay: 6000},
]

function runTask(index) {
    var ul = document.getElementById("notifications");
    var li = document.createElement("li");
    li.appendChild(document.createTextNode(`${tasks[index].message}`));
    ul.appendChild(li);
    if(index < tasks.length - 1){
        setTimeout( () => runTask(index + 1), tasks[index].delay);
    }
}

if(tasks.length > 0) runTask(0); //make sure the task list has at least one element.
票数 0
EN

Stack Overflow用户

发布于 2022-10-29 21:36:06

在现代JavaScript中,在编写异步代码时,async函数可能应该是您的第一个调用端口。它们更清晰,而且通常更容易理解。

在下面的文章中,delay介绍了setTimeout

notify在循环中将li元素添加到文档中,在每次迭代开始时添加一个延迟。

我不确定这是否符合第一个"Hello"的需要。

代码语言:javascript
复制
const delay = (ms) => new Promise((res) => setTimeout(res, ms))
const ul = document.getElementById("notifications")

async function notify(msg, count, ms) {       
    for (let i = 0; i < count; i++) {
      await delay(ms)
      const li = document.createElement('li')
      li.innerText = `${msg} ${Date()}`
      ul.appendChild(li)
    }
}

(async () => {
    await notify('Hello', 1, 5000)
    await notify('Morning', 4, 5000)
    await notify('Evening', 1, 6000)
})()
代码语言:javascript
复制
<p>Notifications will appear below:</p>
<ul id="notifications"></ul>

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74248796

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档