hmm.. I would just make the setTimeout a Promise in itself and then have gas as an async function to call..
async function main() {
  // get the current gwei prices & new price every 5 seconds
  let gas = async () => {
    return new Promise(r=>{
      setTimeout(async()=>r(await getGas()),5e3);
    })
  }
  console.log(await gas()); //whatever getGas should be
  // other code down here
  //whenever you want gas, you can just "await gas()"
}
However.. if you just didn't word your question correctly and you want the variable gas to be updated every 5 seconds in that block of code within recalling main
an async function to call..
async function main() {
  // get the current gwei prices & new price every 5 seconds
  let gas = null; //starting value
  setInterval(async()=>gas=await getGas(),5e3); //every 5 seconds, gas is updated
  console.log(gas); //null
  setTimeout(()=>console.log(gas),6e3); //whatever getGas should be
  // other code down here
  //whenever you want gas, you can just "gas"
}
EDIT: you told me it doesn't work so I give a live example and am now asking how
async function getGas(){
  return Math.floor(Math.random()*5)
}
async function main1() {
  // get the current gwei prices & new price every 5 seconds
  let gas = async () => {
    return new Promise(r=>{
      setTimeout(async()=>r(await getGas()), 5e3);
    })
  }
  setInterval(async()=>
    console.log(await gas(),"~ main1") //whatever getGas should be
  ,1e3);
  // other code down here
  //whenever you want gas, you can just "await gas()"
}
async function main2() {
  // get the current gwei prices & new price every 5 seconds
  let gas = null; //starting value
  setInterval(async()=>gas=await getGas(),5e3); //every 5 seconds, gas is updated
  console.log(gas); //null
  setInterval(()=>
    console.log(gas,"~ main2") //whatever getGas should be
  ,1e3);
  // other code down here
  //whenever you want gas, you can just "gas"
}
main1(); main2();