Search code examples
javascriptnode.jsapisettimeoutcoinbase-api

Call a function every X second in a loop in NodeJS


My objective: Call a function every X second.

I'm using Coinbase pro API and get information of my wallet. There is a limit of API call per second. So I would like to call my function getWalletHistory() for each wallet every 5 seconds.

What I have: my function getWalletList() is called, then I wait for 5 seconds to call my function getWalletHistory().

What I want: Call my function getWalletHistory() for each wallet every 5 seconds.

var wallet_list = [];

getWalletList();

function getWalletList(){
    authedClient.getAccounts().then(wallet_list_response => {
        wallet_list_response.forEach(async wallet => {
            console.log("WALLET LIST:" + wallet.id);
            wallet_list.push(wallet);
        });
        console.log('**********END LOOP WALLET LIST');
        getWalletHistory(wallet_list);
    }).catch(error => {
        // handle the error
        console.log('ERROR getAccounts');
        //console.log(error);
    });
}

const getWalletHistory = async function(wallet_args){
    wallet_args.forEach(async wallet => {
        setTimeout(function(){
            authedClient.getAccountHistory(wallet.id).then(order_list => {
                console.log('*********response');
            }).catch(error => {
                // handle the error
                console.log('ERROR getAccountHistory');
                //console.log(error);
            });
        }, 5000);
    });
}

UPDATE Following the comment of Erenn, I use SetInterval instead of SetTimeout:

var wallet_list = [];

getWalletList();

function getWalletList(){
    authedClient.getAccounts().then(wallet_list_response => {
        wallet_list_response.forEach(async wallet => {
            console.log("WALLET LIST:" + wallet.id);
            setInterval(() => getWalletHistory(wallet), 5000);
        });
        console.log('**********END LOOP WALLET LIST');
    }).catch(error => {
        // handle the error
        console.log('ERROR getAccounts');
        //console.log(error);
    });
}
const getWalletHistory = async function(wallet){
    console.log('*********getWalletHistory:' + wallet.currency);
    authedClient.getAccountHistory(wallet.id).then(order_list => {
        console.log('*********response order_list');
    }).catch(error => {
        // handle the error
        console.log('ERROR getAccountHistory');
        //console.log(error);
    });
}

What I have now: getAccountHistory() is called every 5 seconds for all the wallet in an infinite loop. I would like to call getAccountHistory() every 5 second for only 1 wallet at a time.


Solution

  • You could maintain a queue of list which setInterval could operate on every 5000 ms. Below updated snippet check out getWalletHistories and its comments

    var wallet_list = [];
    getWalletList();
    
    // responisble for maintaining queue (in the form of array) and setting interval
    // Create a new reference of list, pop the item, calls getWalletHistory
    // and once promise gets resolved, move the item back in the list (front of the array)
    function getWalletHistories(walletList) {
      let interval;
      // clear interval counter if getWalletHistories called once again
      if (interval) {
        clearInterval(interval);
      }
      const _list = [...walletList];
      interval = setInterval(() => {
        // pop wallet item from list for get wallet item history
        const wallet = _list.pop();
        getWalletHistory(wallet).then(() => {
          // push the popped wallet item back to the front of list
          _list.unshift(wallet);
        });
      }, 5000);
    }
    
    function getWalletList() {
      authedClient
        .getAccounts()
        .then((wallet_list_response) => {
          getWalletHistories(wallet_list_response);
          console.log("**********END LOOP WALLET LIST");
        })
        .catch((error) => {
          // handle the error
          console.log("ERROR getAccounts");
          //console.log(error);
        });
    }
    
    function getWalletHistories(walletList) {
      let interval;
      // clear interval counter if getWalletHistories called once again
      if (interval) {
        clearInterval(interval);
      }
      const _list = [...walletList];
      interval = setInterval(() => {
        // pop wallet item from list for getting wallet item history
        const wallet = _list.pop();
        getWalletHistory(wallet).then(() => {
          // push the popped wallet item back to the front of list
          _list.unshift(wallet);
        });
      }, 5000);
    }
    
    const getWalletHistory = async function (wallet) {
      console.log("*********getWalletHistory:" + wallet.currency);
      // return the wallet history promise
      return authedClient
        .getAccountHistory(wallet.id)
        .then((order_list) => {
          console.log("*********response order_list", order_list);
        })
        .catch((error) => {
          // handle the error
          console.log("ERROR getAccountHistory");
          //console.log(error);
        });
    };