Как я могу постоянно обновлять текстовое поле статуса в python на фляже? [Дубликат]

Похоже, вы понимаете, как работают интерфейсы, но не уверены в том, когда их использовать и какие преимущества они предлагают. Вот несколько примеров, когда интерфейс имел бы смысл:

// if I want to add search capabilities to my application and support multiple search
// engines such as google, yahoo, live, etc.

interface ISearchProvider
{
    string Search(string keywords);
}

, тогда я мог бы создать GoogleSearchProvider, YahooSearchProvider, LiveSearchProvider и т. Д.

// if I want to support multiple downloads using different protocols
// HTTP, HTTPS, FTP, FTPS, etc.
interface IUrlDownload
{
    void Download(string url)
}

// how about an image loader for different kinds of images JPG, GIF, PNG, etc.
interface IImageLoader
{
    Bitmap LoadImage(string filename)
}

, а затем создать JpegImageLoader, GifImageLoader, PngImageLoader и т. Д.

Большинство надстроек и систем плагинов работают с интерфейсами.

Еще одно популярное использование для шаблона репозитория. Скажем, я хочу загрузить список zip-кодов из разных источников

interface IZipCodeRepository
{
    IList<ZipCode> GetZipCodes(string state);
}

, тогда я мог бы создать XMLZipCodeRepository, SQLZipCodeRepository, CSVZipCodeRepository и т. Д. Для моих веб-приложений я часто создаю хранилища XML на ранней стадии, поэтому я могу получить что-то и запустить до того, как база данных Sql будет готова. Когда база данных будет готова, я напишу SQLRepository для замены версии XML. Остальная часть моего кода остается неизменной, так как она работает с интерфейсами.

Методы могут принимать интерфейсы, такие как:

PrintZipCodes(IZipCodeRepository zipCodeRepository, string state)
{
    foreach (ZipCode zipCode in zipCodeRepository.GetZipCodes(state))
    {
        Console.WriteLine(zipCode.ToString());
    }
}
10
задан davidism 11 August 2015 в 20:18
поделиться

1 ответ

Вы можете передавать данные в ответ, но вы не можете динамически обновлять шаблон так, как вы описываете. Шаблон создается один раз на стороне сервера, а затем отправляется клиенту. Вам нужно будет использовать JavaScript для чтения потокового ответа и вывода данных на стороне клиента.

Используйте XMLHttpRequest, чтобы сделать запрос к конечной точке, которая будет передавать данные. Затем периодически читайте поток, пока он не будет выполнен.

В этом примере используется очень простой формат сообщения: одна строка данных, за которой следует новая строка. Конечно, вы можете так же усложниться в разборе, сколько хотите, пока есть способ идентифицировать каждое сообщение. Например, вы можете вернуть объект JSON и декодировать его на клиенте.

from time import sleep
from flask import Flask, render_template
from math import sqrt

app = Flask(__name__)

@app.route('/')
def index():
    # render the template (below) that will use JavaScript to read the stream
    return render_template('index.html')

@app.route('/stream_sqrt')
def stream():
    def generate():
        for i in range(500):
            yield '{}\n'.format(sqrt(i))
            sleep(1)

    return app.response_class(generate(), mimetype='text/plain')

app.run()
<p>This is the latest output: <span id="latest"></span></p>
<p>This is all the output:</p>
<ul id="output"></ul>
<script>
    var latest = document.getElementById('latest');
    var output = document.getElementById('output');

    var xhr = new XMLHttpRequest();
    xhr.open('GET', '{{ url_for('stream') }}');
    xhr.send();
    var position = 0;

    function handleNewData() {
        // the response text include the entire response so far
        // split the messages, then take the messages that haven't been handled yet
        // position tracks how many messages have been handled
        // messages end with a newline, so split will always show one extra empty message at the end
        var messages = xhr.responseText.split('\n');
        messages.slice(position, -1).forEach(function(value) {
            latest.textContent = value;  // update the latest value in place
            // build and append a new item to a list to log all output
            var item = document.createElement('li');
            item.textContent = value;
            output.appendChild(item);
        });
        position = messages.length - 1;
    }

    var timer;
    timer = setInterval(function() {
        // check the response for new data
        handleNewData();
        // stop checking once the response has ended
        if (xhr.readyState == XMLHttpRequest.DONE) {
            clearInterval(timer);
            latest.textContent = 'Done';
        }
    }, 1000);
</script>
11
ответ дан davidism 21 August 2018 в 07:21
поделиться
  • 1
    Несколько вопросов: 1. В команде xhr.open(), «поток», это имя функции Python, которую она слушает? 2. Есть ли способ не получать все предыдущее сообщение каждый раз (и удалить необходимость в slice(), переменной position и т. Д.? – JeffThompson 11 August 2015 в 22:57
  • 2
    {{ url_for('stream') }} генерирует URL-адрес конечной точке stream при рендеринге шаблона. Невозможно получить только новые данные, вам нужно отслеживать, что было прочитано до сих пор. – davidism 11 August 2015 в 23:00
Другие вопросы по тегам:

Похожие вопросы: