【问题标题】:Flask Countdown Timer烧瓶倒计时
【发布时间】:2020-11-09 05:25:00
【问题描述】:

我正在使用 Flask 构建一个游戏,其中每一轮都有倒计时时间来完成这一轮。我希望时间值每秒减少 1 并在不重新加载页面的情况下进行更新。倒计时本身使用 time.sleep 等待 1 秒,然后将生成器的下一个值设置为全局变量,该变量通过 jsonify 传递到我的 HTML。但是它不起作用。任何帮助将不胜感激!

蟒蛇:

def countdownGen(t):
    return (t-i for i in range(t))

def countdown(t):
    gen = countdownGen(t)
    while t > 0:
        try:
            globaltimer = next(gen)
            time.sleep(1)
        except StopIteration:
            globaltimer = 0

@app.route('/_timer', methods=['GET'])
def timer():
    global globaltimer
    globaltimer = 60
    countdown(globaltimer)
    return jsonify(result=globaltimer)

HTML/JS:

<script type="text/javascript">
  var intervalID = setInterval(update_values,1000);
  $SCRIPT_ROOT = {{request.script_root|tojson|safe}};
  function update_values() {
    $.getJSON($SCRIPT_ROOT + '/_timer',
    function(data) {
      $('#result').text(data.result);
    });
  };
</script>

<body onload="update_values();">
  <span id="result">?</span>
<script>
document.getElementById("result").innerHTML;
</script>
</body>

【问题讨论】:

  • 在声明update_values() 之后,您是否尝试过将setInterval 行移至?
  • @BrunoMonteiro 似乎也不起作用

标签: javascript python html flask jsonify


【解决方案1】:

你可以这样做:

from flask import Flask, render_template, jsonify

app = Flask(__name__)


class Timer:
    def __init__(self, current_time):
        self.current_time = current_time

    def decrement(self):
        if self.current_time > 0:
            self.current_time = self.current_time - 1
        return self.current_time


t = Timer(current_time=60)


@app.route("/", methods=["GET"])
def index():
    return render_template("index.html")


@app.route("/_timer", methods=["GET", "POST"])
def timer():
    new_time = t.decrement()
    return jsonify({"result": new_time})


if __name__ == "__main__":
    app.run()

还有这个:

<body>
   <span id="result"></span>
   <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
   <script>window.jQuery || document.write('<script src="{{ url_for('static', filename='jquery.js') }}">\x3C/script>')</script>
   <script type="text/javascript">
      const root_url = {{request.root_url|tojson|safe}};
      const intervalID = setInterval(update_values, 1000);
      function update_values() {
        $.getJSON(
          root_url + "_timer",
          data => {
            $("#result").text(data.result);
            if (data.result == 0) {
              clearInterval(intervalID);
            }
          }
        )
      }
   </script>
</body>

当我登录request.script_root 时,我得到了一个空字符串,导致请求失败,所以这也可能是你的问题。我改用request.root_urlrequest.root_url 确实有一个斜杠,因此当您尝试使用它调用端点时需要注意这一点。

这里的想法是创建一个类,该类的实例可以传递一个初始时间,该时间可以递减并返回。

在您的代码中,您同时使用setInterval(update_values, 1000)time.sleep(1)。我删除了 time.sleep(1) 调用,因为我们已经每秒只调用 _timer 端点,所以我们不需要再等待一秒钟。

如果时间超过0,我只会减少时间。在模板中如果data.result(即从Flask接收的时间)是0,我们不再递减并清除间隔。

另外请注意,由于我们基于setInterval 递减时间,因此刷新不会重置计时器。这可能是理想的行为,但无论哪种方式都需要牢记。

【讨论】:

  • 这段代码非常适合我,谢谢。但是,我从 get 请求中返回了一个空值,而不是 t 中的值。我不知道这是否是改进它的最佳方法,但不是:new_time = t.decrement() return jsonify({"result": new_time}) 我做了t.decrement() return jsonify({"result":t.current_time})
猜你喜欢
  • 1970-01-01
  • 2021-05-17
  • 2019-05-25
  • 1970-01-01
  • 2019-01-04
  • 2019-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多