Plataforma de compras, carga 10 artículos cada segundo

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.

Pedir valor no necesita gasolina. Es básicamente solo una solicitud para obtener un artículo.

Respuestas (1)

Esto se puede hacer desde javascript, usando setInterval(), o setTimeout():

Si no le importa si el código dentro de timerpuede 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 setTimeoutjunto con una self-executing anonymousfunció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.calleeen este ejemplo como referencia de función. Es una mejor manera de dar un nombre a la función y llamarla dentro setTimeoutporque arguments.calleeestá 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);
        }
    });
}
Gracias por el comentario, parece que nos acercamos a ello. Lo que hago es enviar una solicitud a getArticlesAmount que me da por ejemplo 559 si hay 559 artículos. Para obtener ahora los últimos 10, hago un bucle while hasta que obtengo los artículos de id 549 a 559. Luego llamo a getArticlesAmount con el id dentro del bucle while. ¿Cuál es la mejor manera ahora de integrar su idea con el tiempo de espera o el intervalo?
Creo que quisiste decir que llamas getArticle( _id )desde dentro de tu bucle. ¿ Puedes poner aquí la línea donde llamas getArticle( _id )?
¡Lo siento! Olvidé agregar el código javascript que uso. Ahora lo he agregado.
He actualizado mi respuesta. Espero que resuelva tu problema.
¡Gracias! Lo he probado y casi funciona. El problema: Devuelve 10 veces el mismo artículo. Entonces en mi caso tengo 19 artículos y en vez de regresar mostrando la información actualizada de los artículos 9 al 19, solo la muestra del artículo 19 pero eso 10 veces.
ok, actualicé el js, para usar el real ien lugar de su último valor.
Wow gracias, funcionó, muchas gracias! ¿Puede explicar brevemente qué sucede aquí, por ejemplo, qué hace .bind? No estoy 100% seguro de cómo funcionó.
De nuevo, muchas gracias. Me ayudó mucho y ahora puedo resolver mis problemas. Realmente feliz por la solución!