У меня есть веб-сайт, на котором пользователи могут продавать статьи, которые будут сохранены в блокчейне Эфириума. На этом сайте топ выглядит следующим образом:
<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 «обновителей/обратных отсчетов».
Большое спасибо за ответы.
Это можно сделать из 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);
}
});
}
getArticle( _id )
из своего цикла. Можете ли вы указать здесь линию, по которой вы звоните getArticle( _id )
?i
вместо последнего значения.
ДКБ