Tengo un sitio web donde los usuarios pueden vender artículos que se guardarán en la cadena de bloques de ethereum. En ese sitio web, la parte superior se ve de la siguiente manera:
<div id="recentArticles"></div>
El contrato incluye lo siguiente (escribí solo las partes importantes):
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;
}
El código 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();
Ahora quiero lo siguiente: cuando un usuario visita el sitio web, debe hacer una llamada al contrato para cargar los 10 artículos recientes y mostrarlos en el div "artículos recientes". Eso es fácil y lo hice con éxito. Pero ahora viene la parte donde necesito ayuda.
Quiero, que cada segundo se haga otra llamada al contrato para sacar los últimos valores de los 10 artículos llamados.
Ejemplo: El usuario llega al sitio y lo ve. Cargó los últimos 10 artículos. Alguien pujó por un artículo. El artículo en el div ahora debería mostrar la nueva oferta.
¿Cuál es la mejor manera de hacer una función que haga una llamada cada segundo para cada artículo? Necesitaría 10 "actualizadores/cuenta atrás".
Muchas gracias por las respuestas.
Esto se puede hacer desde javascript, usando setInterval()
, o setTimeout()
:
Si no le importa si el código dentro de timer
puede demorar más que su intervalo, use setInterval()
:
setInterval(function_that_checks_the_price_for_a_product, delay)
Eso activa la función pasada como primer parámetro una y otra vez.
Un mejor enfoque es, para usar setTimeout
junto con una self-executing anonymous
función:
(function(){
// do some stuff
setTimeout(arguments.callee, 15000); //execute itself every 15 seconds - the avg block time on ethereum
})();
eso garantiza que la próxima llamada no se realice antes de que se ejecute su código. Lo usé arguments.callee
en este ejemplo como referencia de función. Es una mejor manera de dar un nombre a la función y llamarla dentro setTimeout
porque arguments.callee
está en desuso en ecmascript 5.
Usando setInterval()
, su initiateArticles()
función se vería así:
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);
}
});
}
y también cambiar la función getArticle()
a:
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 )
desde dentro de tu bucle. ¿ Puedes poner aquí la línea donde llamas getArticle( _id )
?i
en lugar de su último valor.
dkb