I want to create a function that enqueues callback functions, but doesn't return until that callback has been dequeued and executed.
function executeCallback(callback) {
    if( shouldEnqueue ) {
      enqueue(callback);
      // awaits execution of callback
      // return executed callback's return value
    } else {
      return callback()
    }
}
The actual function works as follows. When an orderbook is needed, we will check to see if we have a recent one cached. If we don't have a recent one, we will queue the request for a fresh orderbook. We will then return the orderbook once it has been requested. The actual code will look something like this:
const axios = require("axios");
const moment = require("moment");
const { promisify } = require("util");
const orderbookQueue = [];
const orderbookUpdateTime = {};
async function requestOrderbook(pair) {
  const response = await axios.post("https://api.kraken.com/0/public/Depth", {
    pair
  });
  orderbookUpdateTime[pair] = +moment();
  return response.data.result[pair];
}
async function getOrderbook(pair, currentTime) {
  if (
    orderbookUpdateTime[pair] &&
    currentTime - orderbookUpdateTime[pair] > 60000
  ) {
    const requestOrderbookAsync = promisify(requestOrderbook);
    orderbookQueue.push(() => requestOrderbookAsync(pair));
    // how to I return the result of requestOrderbookAsync when it has been called ?
  }
  return requestOrderbook(pair);
}
const queueExecutor = function queueExecutor() {
  while (orderbookQueue.length) {
    orderbookQueue[0]();
    orderbookQueue.shift();
  }
};
 
    