The asynchronous flow of Node crawler is difficult to control, how to modify it into the form of Promise or Async/Await

the following code, I want to print out the final result ans array, it is very difficult to print, because the print operation is Synchronize, always print is empty, for asynchronous flow control, how to modify the form of Promise or Async/Await?

const cheerio = require("cheerio");
const http = require("http");
const iconv = require("iconv-lite");

let baseUrl = "http://www.ygdy8.net/html/gndy/dyzz/list_23_";
let Host = "http://www.ygdy8.net/";

const totalPage = 2; //
let ans = [];
//
function getTitleHref(url,page) {
  let startUrl = url+page+".html";
  http.get(startUrl,function(res) {
    const { statusCode } = res;
    let chunks = [];
    res.on("data",function(chunk){
      chunks.push(chunk);
    });
    res.on("end",function(){
      let title = [];
      
      let html = iconv.decode(Buffer.concat(chunks),"gb2312");
      let $ = cheerio.load(html, {decodeEntities: false});
      // console.log($);
      $(".co_content8 .ulink").each(function(i,d) {
        let $d = $(d);
        let titleHref = [];
        titleHref.push({
          href: $d.attr("href")
        });
        getLink(titleHref,(ans)=>{console.log(ans)})
      });
      // console.log(ans);
    });  
  });
}


// /*
//
function getLink(titleHref,cb) {
  console.log("getLink");
  console.log(titleHref);
  if(titleHref) {
    titleHref.forEach(function(v,k) {
      console.log("~~~~~~~~~~~~~~~~~~~~");
      let infoUrl = Host + v.href;
      // console.log(infoUrl);
    
        http.get(infoUrl,function(res) {
          const { statusCode } = res;
          const contentType = res.headers["content-type"];
        
          let error;
          if (statusCode !== 200) {
            error = new Error("\n" +
                             `: ${statusCode}`);
          } 
          if (error) {
            console.error(error.message);
            // 
            res.resume();
            return;
          }
          console.log("getlink http");
          let chunks = [];
          res.on("data",function(chunk) {  
            chunks.push(chunk);
          });
          res.on("end", function(){
            try {
              let html = iconv.decode(Buffer.concat(chunks),"gb2312");
              let $ = cheerio.load(html, {decodeEntities: false});
              let bt = "";
              bt = $("-sharpZoom td").children("a").attr("href");
              // console.log(bt);
              // console.log(typeof bt)
              ans.push(bt);
              cb(ans);
            }catch (e) {
              console.error("bt",e.message);
            }
          })
        }).on("error", (e) => {
          console.error(`: ${e.message}`);
        });
    });
  }
};
// */
for(let i = 1; i <= totalPage; iPP) {
  getTitleHref(baseUrl,i);
};



Mar.22,2021

encapsulates the http.get and throws a Promise instance, and in the end event resolve, reject in the error event.
change forEach to Promise.all+map
await Promise.all is the result you want

MySQL Query : SELECT * FROM `codeshelper`.`v9_news` WHERE status=99 AND catid='6' ORDER BY rand() LIMIT 5
MySQL Error : Disk full (/tmp/#sql-temptable-64f5-1b3a673-2c202.MAI); waiting for someone to free some space... (errno: 28 "No space left on device")
MySQL Errno : 1021
Message : Disk full (/tmp/#sql-temptable-64f5-1b3a673-2c202.MAI); waiting for someone to free some space... (errno: 28 "No space left on device")
Need Help?