【问题标题】:How to keep running an async function over and over again, once each task is completed完成每个任务后,如何一遍又一遍地运行异步功能
【发布时间】:2021-02-19 09:22:05
【问题描述】:

这个小任务让我很头疼。

我只想让 puppeteer 访问游戏站点,然后等待 6 球结果出现在 Dom 中,然后获取每个球元素的 class[1] 及其互文,然后将其保存到 mongo dB 数据库。

当我运行 node index.js 时,它只运行一次。但我想要做的是,一旦异步函数运行并获取数据并将其发送到数据库,我希望它等待 3-5 秒然后再次运行。并继续重复同样的过程。

--- 访问游戏网站 --- 刮 6 球结果 --- 将结果保存到数据库 --- 然后从第 1 步开始重复。

我不想使用 setInterval,因为我真的不知道异步函数什么时候会完成它。

所以我只是在寻找一种方法,可以让异步函数在运行时返回一个值,所以通过返回值,我可以知道它已经完成了任务,然后我会再次运行它。

我已经包含了我尝试过的解决方案,但结果并不稳定。 iife 方法只运行两次。 .then promise 方法根本不起作用,我注释掉了下面的两个解决方案

请问我做错了什么??或者可能是scrapedata函数本身写得不好。有人请帮我纠正它。

var http = require("http");
const mongoose = require("mongoose");
const puppeteer = require("puppeteer");

mongoose.connect("mongodb://localhost:27017/gameDb", { useNewUrlParser: true, useUnifiedTopology: true, });
const gameSchema = new mongoose.Schema({time: String, ball1color: String, ball1number: Number, ball2color: String, ball2number: Number, ball3color: String, ball3number: Number, ball4color: String, ball4number: Number, ball5color: String, ball5number: Number, ball6color: String, ball6number: Number});

async function scrapeData(url){
const browser = await puppeteer.launch({ headless:false, args: ['--no-sandbox'] });
const page = await browser.newPage();
await page.goto(url);

//wait for the elements that i want to scrape to become visible in the Dom
await page.waitForFunction(()=>{
  return document.querySelectorAll('.ball')[2] && document.querySelectorAll('.ball')[2].style.visibility != 'hidden' && document.querySelectorAll('.ball')[3] && document.querySelectorAll('.ball')[3].style.visibility != 'hidden' && document.querySelectorAll('.ball')[4] && document.querySelectorAll('.ball')[4].style.visibility != 'hidden' && document.querySelectorAll('.ball')[5] && document.querySelectorAll('.ball')[5].style.visibility != 'hidden' && document.querySelectorAll('.ball')[6] && document.querySelectorAll('.ball')[6].style.visibility != 'hidden' && document.querySelectorAll('.ball')[7] && document.querySelectorAll('.ball')[7].style.visibility != 'hidden';
}, {timeout: 100000 });

//wait for the innertext of the 6 balls to appear
await page.waitForFunction(() => {
return document.querySelectorAll(".ball")[2].innerText !== '' && document.querySelectorAll(".ball")[3].innerText !== '' && document.querySelectorAll(".ball")[4].innerText !== '' && document.querySelectorAll(".ball")[5].innerText !== '' && document.querySelectorAll(".ball")[6].innerText !== '' && document.querySelectorAll(".ball")[7].innerText !== '';
 }, { timeout: 100000 });

 //get the color and no of the six balls starting from the left
const [ball1, ball2, ball3, ball4, ball5, ball6] = await page.evaluate(() => {
const ball1 = document.querySelectorAll(".ball")[2]; const ball2 = document.querySelectorAll(".ball")[3];
const ball3 = document.querySelectorAll(".ball")[4]; const ball4 = document.querySelectorAll(".ball")[5]; 
const ball5 = document.querySelectorAll(".ball")[6]; const ball6 = document.querySelectorAll(".ball")[7];
 //return the color and their numbers
return [
{number: ball1.innerText,color: ball1.classList[1].split('-')[1]},{number: ball2.innerText,color: ball2.classList[1].split('-')[1]},
{number: ball3.innerText,color: ball3.classList[1].split('-')[1]},{number: ball4.innerText,color: ball4.classList[1].split('-')[1]},
{number: ball5.innerText,color: ball5.classList[1].split('-')[1]},{number: ball6.innerText,color: ball6.classList[1].split('-')[1]}
  ];
  });

  var gotData;

  //convert time to nigeria timezone 
  function convertTZ(date, tzString) {
    return new Date((typeof date === "string" ? new Date(date) : date).toLocaleString("en-US", {timeZone: tzString}));   
}
const convertDate = convertTZ(new Date(),"Africa/Lagos");

 //change convert getMonth() to human readable formart
 var thisMonth;
switch(convertDate.getMonth()){ case 0: thisMonth = "january"; break; case 1: thisMonth = "february"; break; case 2: thisMonth = "march"; break; case 3: thisMonth = "april"; break; case 4: thisMonth = "may"; break; case 5: thisMonth = "june"; break; case 6: thisMonth = "july"; break; case 7: thisMonth = "august"; break; case 8: thisMonth = "september"; break; case 9: thisMonth = "octomber"; break; case 10: thisMonth = "november"; break; case 11: thisMonth = "december"; break; default: thisMonth = "invalid_month";} 

//create a db collection, name it using today date & month in nigeria timezone
  var dbCollection = thisMonth+"_"+convertDate.getDate();

  //get the current time in Nigeria timezone & save it to a variable
const gameTime = convertDate.getHours()+":"+convertDate.getMinutes()+":"+convertDate.getSeconds();

  //write the result to the database
const collection = mongoose.model(dbCollection, gameSchema);

const Result = new collection({
time: gameTime, ball1color: ball1.color, ball1number: ball1.number,
ball2color: ball2.color, ball2number: ball2.number, 
ball3color: ball3.color, ball3number: ball3.number,
ball4color: ball4.color, ball4number: ball4.number,
ball5color: ball5.color, ball5number: ball5.number,
ball6color: ball6.color, ball6number: ball6.number,
});

Result.save((err, savedDoc, rowsAffected)=>{
if(err){
  gotData = false;
 //return gotData;
}else{
  gotData = true; 
//return gotData;
}
});

 //close the browser
 await browser.close();

 return gotData;
}

// scrapeData("https://logigames.bet9ja.com/Games/Launcher?gameId=11000&provider=0&sid=&pff=1&skin=201").then(isSaved)=>{
//  if(isSaved == true){
//    scrapeData("https://logigames.bet9ja.com/Games/Launcher?gameId=11000&provider=0&sid=&pff=1&skin=201");
//  }else if(isSaved == false){
//  scrapeData("https://logigames.bet9ja.com/Games/Launcher?gameId=11000&provider=0&sid=&pff=1&skin=201");
//  }else{
//    console.log(isSaved + " something is really wrong");
//  }
//    });

// (async ()=>{
//   const isSaved = await scrapeData("https://logigames.bet9ja.com/Games/Launcher?gameId=11000&provider=0&sid=&pff=1&skin=201");
//   if(isSaved == true){
//     scrapeData("https://logigames.bet9ja.com/Games/Launcher?gameId=11000&provider=0&sid=&pff=1&skin=201");
//   }else if(isSaved == false){
//   scrapeData("https://logigames.bet9ja.com/Games/Launcher?gameId=11000&provider=0&sid=&pff=1&skin=201");
//   }else{
//     console.log(isSaved + " something is really wrong");
//   }
// })();

http.createServer((request, response)=>{
  if(request.url == "/" && request.method == "GET"){
  response.writeHead(200, { 'Content-Type': 'text/html' });
  response.end("your app is working", "utf-8");
  }
  
}).listen(process.env.PORT || 3000,()=>{console.log("server working")});

【问题讨论】:

    标签: javascript node.js mongodb async-await puppeteer


    【解决方案1】:

    我希望它等待 3-5 秒然后再次运行。并继续重复同样的过程。

    只需使用一个while循环和一个promisified setTimeout:

    const wait = ms => new Promise(r => setTimeout(r, ms));
    
    (async => {
      while (true) {
        const isSaved = await scrapeData(url);
        // ...
        await wait(5000);
      }
    })();
    

    【讨论】:

      【解决方案2】:

      这里有四个任务。请注意,它们都是async 函数。函数的内部工作方式可以是同步的,也可以是异步的。

      start() 函数是递归的。它使用链接将每个任务按顺序排列。等待函数是一个可以调整的简单超时。

      在这个例子中,我在四次迭代后停止它。它可以通过删除条件连续运行。

      注意:您必须释放您在每个任务方法中创建的所有资源。如果您不小心自己清理后,此代码很容易出现内存泄漏。在每个任务的返回语句之前,将函数中创建的所有对象设置为null

      async function doTask1() {
        console.log('doing task1...');
        return true;
      }
      async function doTask2() {
        console.log('doing task2...');
        return true;
      }
      async function doTask3() {
        console.log('doing task3...');
        return true;
      }
      async function doTask4() {
        console.log('doing task4...');
        return true;
      }
      
      function wait() {
        return new Promise((res, rej) => {
          if (counter < 3) {
            console.log('----- waiting -----');
            counter++;
            setTimeout(res, 2000);
          } else {
            console.log('----- DONE -----');
            rej();
          }
        });
      }
      
      let counter = 0;
      
      function start() {
        doTask1().then(doTask2).then(doTask3).then(doTask4).then(wait).then(start);
      }
      
      start();

      【讨论】:

        猜你喜欢
        • 2021-11-04
        • 2015-02-03
        • 2011-07-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多