首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在每个任务完成后一遍又一遍地运行异步函数

如何在每个任务完成后一遍又一遍地运行异步函数
EN

Stack Overflow用户
提问于 2021-02-18 23:53:40
回答 2查看 51关注 0票数 2

这个小任务真让我头疼。

我只想让木偶人访问游戏站点,然后等待6个球的结果出现在Dom中,然后获取每个球元素的class1和它们的互文,然后将其保存到mongo dB数据库。

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

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

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

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

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

我做错了什么??或者可能是scrapedata函数本身写得不好。谁来帮我改正一下。

代码语言:javascript
运行
复制
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")});

EN

回答 2

Stack Overflow用户

发布于 2021-02-19 09:15:50

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

只需使用while循环和promisified setTimeout:

代码语言:javascript
运行
复制
const wait = ms => new Promise(r => setTimeout(r, ms));

(async => {
  while (true) {
    const isSaved = await scrapeData(url);
    // ...
    await wait(5000);
  }
})();
票数 1
EN

Stack Overflow用户

发布于 2021-02-19 01:03:44

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

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

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

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

代码语言:javascript
运行
复制
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();

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66263451

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档