Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

119
Vistas
Using a Promise to check if a new random number has been generated

I'm using Chainlink Oracles to get random numbers. This process of getting a random number takes a while. In order to do that, I have to execute this line (asynchronous call), which calls a function of my smart contract an stores the new random number:

const newRandomNumber = await contract.connect(signer).randomResult(); 

What I want is to automate this process: when a new number is generated (and it is available for use), I would like to display a message to the user (in my fronted).

Hey, a new number has been generated.

How could I periodically check if the result stored in newRandomNumber has changed? And how could I display a message when that has happened?

about 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

tl;dr

Create an Observable to periodically call an API-endpoint:

import { distinctUntilChanged, switchMap, timer } form 'rxjs'; /* Use RxJS library for convenience */

const getRandomNumber = contract.connect(signer).randomResult();

const observable = timer(0, 1000) /* Trigger now and each 1000 ms */
    .pipe(
        switchMap(getRandomNumber), /* On each run, get the current number */
        distinctUntilChanged(), /* Only trigger subscribers if new number */
    )

const subscription = observable.subscribe((number) => console.log(number));

/* Don't forget to unsubscribe after, e.g. when the component unmounts */
subscription.unsubscribe();

Long version

The observer pattern allows you to receive notifications (e.i. 'subscribe') to multiple asynchronous events - the same way a javascript Promise notifies you after a single asynchronous event finished. (Observers are actually much more flexible than that, this is merely one usecase)

A naive javascript implementation

Let's see how we could implement your desired behavior in basic javascript

let currentRandomNumber = null;
let isCanceled = false;

async function checkAndUpdateNumber() {
  while (!isCanceled) {
    /* Set your new (or same) number */
    currentRandomNumber = await contract.connect(signer).randomResult();

    /* Wait 1000ms */
    await new Promsie((resolve) => setTimeout(resolve, 1000));
  }
}
checkAndUpdateNumber();

/* If you want to stop the loop */
isCancelled = true;

This implementation works but leaves much room for improvement. The code is not reusable in the slightest and is not easily testable.

Observers provide you with a much cleaner interface to handle multiple asynchronous operations. Check out this article to get an idea of how observers work under the hood.

The go-to javascript library for observables is RxJS. It is well tested and provides countless utility methods so I'd highly recommend you to check it out.

about 4 years ago · Santiago Trujillo Denunciar

0

Because you tagged React on your question, here's a commented example using React state:

<div id="root"></div><script src="https://unpkg.com/react@17.0.2/umd/react.development.js"></script><script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js"></script><script src="https://unpkg.com/@babel/standalone@7.16.6/babel.min.js"></script>
<script type="text/babel" data-type="module" data-presets="env,react">

const {useEffect, useState} = React;

// simulate making a network request to get a random number from an API:
// it will return a promise which will (at some point in the future)
// resolve with the random number, or reject with an Error
function mockFetchRandomNumber () {
  const randomNumber = Math.floor(Math.random() * 1000) + 1; // 1-1000
  const delay = Math.floor(Math.random() * 1000) + 1000; // 1-2s
  const chance = 0.2; // percent chance of random network failure
  return new Promise((resolve, reject) => setTimeout(() => {
    if (chance > Math.random()) reject(new Error('Network error'));
    else resolve(randomNumber);
  }, delay));
}

// a custom hook to wrap the logic of fetching the random number
// and maintain the state of the request while doing so
function useRandomNumber () {
  const [data, setData] = useState(); // the potential data
  const [error, setError] = useState(); // a potential error
  const [isLoading, setIsLoading] = useState(false); // whether the request is still pending
  const [reloadBoolean, setReloadBoolean] = useState(false);

  useEffect(() => {
    const fetchData = async () => {
      setIsLoading(true);
      setData(undefined);
      setError(undefined);
      try {
        const randomNumber = await mockFetchRandomNumber();
        setData(randomNumber);
        setError(undefined);
      }
      catch (ex) {
        setError(ex instanceof Error ? ex : new Error(String(ex)));
        setData(undefined);
      }
      setIsLoading(false);
    };
    fetchData();
  }, [reloadBoolean, setData, setError, setIsLoading]);

  return {
    data,
    error,
    isLoading,
    // will toggle the value of `reloadBoolean`, forcing a re-render
    reload: () => setReloadBoolean(b => !b),
  };
}

function Example () {
  const {data, error, isLoading, reload} = useRandomNumber();
  return (
    <div>
      {
        isLoading
          ? (<div>Loading random number...</div>)
          : null
      }
      {
        error
          ? (<div>There was an error loading the data ({error.message})</div>)
          : null
      }
      {
        data
          ? (<div>The random number is: {data}</div>)
          : null
      }
      <button onClick={reload}>Get new number</button>
    </div>
  );
}

ReactDOM.render(<Example />, document.getElementById('root'));

</script>

about 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda