Платформа магазина, загружайте 10 статей каждую секунду

У меня есть веб-сайт, на котором пользователи могут продавать статьи, которые будут сохранены в блокчейне Эфириума. На этом сайте топ выглядит следующим образом:

<div id="recentArticles"></div>

Контракт включает в себя следующее (я написал только важные части):

struct Article {
    address seller;
    uint bid;
    uint bidder;    
}

Article[] articles;

function getArticle(uint _id) returns(address seller, uint bid, uint bidder){
    return(articles[_id].seller,articles[_id].bid,articles[_id].bidder);
}

function getArticlesAmount() returns(uint amount) {
    return articles.length;
}

Код JavaScript:

function initiateArticles() {
    contract.getArticleAmount({from: web3.eth.accounts[0]},function(error, result)
    {
        if(!error)
        {
            i = 0;
            while(i <= result) {
                getArticle(i)
                i++;
            }
        }
        else {
            console.log(error);
        }
    });
}

function getArticle(id) {
    contract.getArticle(id, {from: web3.eth.accounts[0]},function(error, result)
    {
        if(!error)
        {
            document.getElementById("recentArticles").innerHTML = document.getElementById("recentArticles").innerHTML + result[0] + result[1]...;
            ## This is not the finished code. Here I need help.
        }
        else {
            console.log(error);
        }
    });
}

document.onload = initiateArticles();

Теперь я хочу следующее: когда пользователь посещает веб-сайт, он должен вызвать контракт, чтобы загрузить 10 последних статей и показать их в div «recentArticles». Это легко, и я сделал это успешно. Но сейчас наступает та часть, где мне нужна помощь.

Я хочу, чтобы каждую секунду в контракт выполнялся еще один вызов, чтобы получить последние значения 10 вызываемых статей.

Пример: Пользователь заходит на сайт и просматривает его. Он загрузил последние 10 статей. Кто-то сделал ставку на статью. Теперь статья в div должна отображать новую ставку.

Как лучше всего сделать функцию, которая будет вызывать каждую секунду для каждой статьи? Мне понадобится 10 «обновителей/обратных отсчетов».

Большое спасибо за ответы.

Запрос значения не нуждается в газе. По сути, это просто запрос к getArticle.

Ответы (1)

Это можно сделать из javascript, используя либо setInterval(), либо setTimeout():

Если вам все равно, может ли код внутри timerможет занять больше времени, чем ваш интервал, используйте setInterval():

setInterval(function_that_checks_the_price_for_a_product, delay)

Это снова и снова запускает функцию, переданную в качестве первого параметра.

Лучшим подходом является использование setTimeoutвместе с self-executing anonymousфункцией:

(function(){
    // do some stuff
    setTimeout(arguments.callee, 15000); //execute itself every 15 seconds - the avg block time on ethereum
})();

это гарантирует, что следующий вызов не будет сделан до того, как ваш код будет выполнен. Я использовал arguments.calleeв этом примере как ссылку на функцию. Это лучший способ дать функции имя и вызвать его внутри, setTimeoutпотому что arguments.calleeэто устарело в ecmascript 5.

Используя setInterval(), ваша initiateArticles()функция будет выглядеть так:

function initiateArticles() {
    contract.getArticleAmount({from: web3.eth.accounts[0]},function(error, result)
    {
        if(!error)
        {
            i = 0;
            while(i <= result) {
                //need a wrapper anonymous function so we can send the i param to getArticle()
                setInterval(getArticle.bind({articleId: i}), 15000);
                i++;
            }
        }
        else {
            console.log(error);
        }
    });
}

а также измените функцию getArticle()на:

function getArticle() {
    const id = this.articleId;
    contract.getArticle(id, {from: web3.eth.accounts[0]},function(error, result)
    {
        if(!error)
        {
            document.getElementById("recentArticles").innerHTML = document.getElementById("recentArticles").innerHTML + result[0] + result[1]...;
            ## This is not the finished code. Here I need help.
        }
        else {
            console.log(error);
        }
    });
}
Спасибо за комментарий, кажется, мы подошли к этому ближе. Что я делаю, так это отправляю запрос в getArticlesAmount, который дает мне, например, 559, если есть 559 статей. Чтобы получить последние 10 статей, я делаю цикл while, пока не получу статьи с идентификатором от 549 до 559. Затем я вызываю getArticlesAmount с идентификатором внутри цикла while. Как лучше всего интегрировать вашу идею с тайм-аутом или интервалом?
Я думаю, вы хотели сказать, что звоните getArticle( _id )из своего цикла. Можете ли вы указать здесь линию, по которой вы звоните getArticle( _id )?
Извини! Я забыл добавить код javascript, который я использую. Я сейчас добавил.
Я обновил свой ответ. Надеюсь, это решит вашу проблему
Спасибо! Я пробовал, и это почти сработало. Проблема: он возвращает 10 раз одну и ту же статью. Итак, в моем случае у меня есть 19 статей, и вместо того, чтобы возвращать обновленную информацию для статей с 9 по 19, она показывает ее только из статьи 19, но это 10 раз.
хорошо, я обновил js, чтобы использовать фактическое iвместо последнего значения.
Вау, спасибо, это сработало, большое спасибо! Не могли бы вы вкратце объяснить, что здесь происходит, например, что делает .bind? Я не уверен на 100%, как это работает.
Большое спасибо еще раз. Это очень помогло, и теперь я могу решить свои проблемы. Очень рад за решение!