【问题标题】:JavaScript: How to auto increment a counter asynchronously [duplicate]JavaScript:如何异步自动递增计数器[重复]
【发布时间】:2020-09-10 02:19:18
【问题描述】:

我想在点击后自动增加一个计数器而不阻止与浏览器的交互。我知道我需要 setTimeoutsetInterval ,但不知道如何实现。任何帮助将不胜感激。
这是代码

HTML

<button id="start">start</button>

JavaScript

let start= document.querySelector('#start'); 

const counter = () => {
  for(let i = 0; i<1000; i++){
  console.log(i)
 }
}

start.addEventListener("click", counter);

【问题讨论】:

  • 大多数 javascript 被阻塞。 stackoverflow.com/questions/36588775/… --- 虽然它在谈论承诺
  • @evolutionxbox 不,不是,请参阅网络工作者。
  • “但不知道如何实现”阅读some documentation 可能是一个好的开始...
  • @JuanMendes 我知道网络工作者,但这不是语言功能。那是一个网络API。即使在 web worker 内部,JS 仍然是单线程的。
  • ECMAScript 没有说明它是阻塞的还是单线程的或其他任何东西。大多数实现都是单线程的(在某种程度上)。无论如何,这几乎不是讨论这个的地方,@JuanMendes,evolutionxbox...

标签: javascript


【解决方案1】:

设置一个 Promise 并等待到运行时。

const start = document.getElementById("start");
const bar = document.getElementById("bar");
const percent = document.getElementById("percent");
const results = document.getElementById("results");

let promisseId = 0;

const counter = (n = 100) => {
  if (n > 100) {
    n = 100;
  }

  promisseId++;

  return new Promise((resolve) => {
    // Here you can set a reject, (resolve, reject) the reject() must run in case your counter throws an error...
    const id = promisseId;

    let i = 1; // i is set outsite.
    const interval = setInterval(function() {
      if (i === n) {
        clearInterval(interval);
        resolve({
          i,
          id
        });
      }
      bar.value = i++;
    }, 100);
  });
};

start.addEventListener(
  "click",
  () =>
    counter(parseInt(this.percent.value)).then((res) => {
    const p = document.createElement("p");
    p.innerText = `Promise ${res.id} resolved! It goes to ${res.i}%`;
    results.appendChild(p);
  })
); // console.log the "res" when its resolved! You can use another value instead of 100 at counter(100).
<input id="bar" type="range" min="1" max="100" value="1" /> Go to <input id="percent" type="number" value="100" />% |
<button id="start">Start</button>
<p>Run it multiple times and simultaneously w/ different values, to see the magic!</p>
<div id="results"></div>

在上面的示例中,尝试启动 100% 执行并立即执行 10%,您将看到 10% 的执行在完整执行之前结束。

为了使它完整,这将是一个同时使用解决和拒绝的案例:

new Promise((resolve, reject) => {
  if (yourCondition) {
    resolve('Something to return as Success');
  } else {
    reject('Something to return on Failed');
  }
});

【讨论】:

  • @Iago Calazans 非常感谢您的回答。你的答案是我想要的,而且非常聪明。但我无法运行它。给出“ Uncaught SyntaxError: Unexpected token '{'”。请你看一下好吗?
  • 嘿@Greg,我成功了!对不起这个小错误!
  • 嘿@Iago Calazans,感谢您的快速回复。我做到了,现在它没有抛出任何错误,但是控制台没有输出。
  • 现在代码运行,但最后抛出此错误“未捕获(在承诺中)ReferenceError: i is not defined”
  • 嘿@Iago Calazans 不幸的是没有。它不是异步的,在单击按钮上不起作用,请查看此处codesandbox.io/s/wonderful-cdn-ro439?file=/src/…
【解决方案2】:

const output = document.getElementById("output");
 
function start() {
  let counter = 0;
  setInterval(() => {
    output.innerHTML = ++counter;
  }, 1000);
}
<div id="output">0<div>
<button onclick="start()">Start</button>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-24
    • 2016-02-03
    相关资源
    最近更新 更多