简体   繁体   English

如何处理Node.js的异步行为-Puppeteer?

[英]How to handle asynchronous behaviour of Node.js - Puppeteer?

So basically I am using puppeteer to download a CSV file and then read the CSV file and then create a new file with my naming structure and sore that data in the dropbox folder. 因此,基本上,我正在使用puppeteer下载CSV文件,然后读取CSV文件,然后使用我的命名结构创建一个新文件,并将该数据放在dropbox文件夹中。 This process is repeated again and again for different accounts. 对于不同的帐户,此过程一次又一次地重复。 The problem is that due to the asynchronous behavior of the node.js, it starts downloading the other file and doesn't wait for the file writing process to get completed. 问题在于,由于node.js的异步行为,它开始下载另一个文件,而不等待文件写入过程完成。 Due to this problem, the file gets stored in the wrong folder since the folder name is also passed in the loop. 由于此问题,由于文件夹名称也在循环中传递,因此文件存储在错误的文件夹中。 How can I solve this issue? 我该如何解决这个问题?

     const puppeteer = require('puppeteer');
     var datetime = require('node-datetime');
     var dt = datetime.create();
     dt.offsetInDays(-2);
     var start_date = dt.format('Y-m-d');
     dt.offsetInDays(1);
     var end_date = dt.format('Y-m-d');
     dt.offsetInDays(0);
     var date =  dt.format('Y-m-d');
     var fs = require('fs'),
     path = require('path'),
     _ = require('underscore');
     var user_details = [
          {
               username : 'user1', 
               password : 'password1',
               folder_name : 'folder1'
          },
          {
               username : 'user2',
               password : 'password2',
               folder_name : 'folder2'
          },
          {
               username : 'user3',
               password : 'password3',
               folder_name : 'folder3'
          },
          {
               username : 'user4',
               password : 'password4',
               folder_name : 'folder4'

          }];


     (async () => {

          console.log(user_details.length); 
          for( var i=0; i<user_details.length; i++){               
          var username = user_details[i]['username'];
          var password = user_details[i]['password'];
          var folder_name = user_details[i]['folder_name'];
          console.log(username);
          console.log(folder_name);
          const browser = await puppeteer.launch({ headless: false});
          const page = await browser.newPage();
          await page.goto('url', {waitUntil: 'networkidle2'});
          await page.waitFor('input[name=name]');
          await page.$eval('input[name=name]', (el, _username) => el.value = _username, username);
          await page.$eval('input[name=password]', (el, _password) => el.value = _password, password);
          await page.click('input[type=submit]');
          await page.waitFor('.breadcrumb')
          await page.goto('url', {waitUntil: 'networkidle2'});
          await page.waitForSelector('.csv_toggle');
          await page.click('.action');
          await page.click('.fa-files-o');  
          await page.waitFor(10000);
          var dir = '/users/user/Downloads/';
          var files = fs.readdirSync(dir);

          // use underscore for max()
          var file_name =  _.max(files, function (f) {
               var fullpath = path.join(dir, f);

               // ctime = creation time is used
               // replace with mtime for modification time
               return fs.statSync(fullpath).ctime;
          });
          var filePath = path.join('/users/user/Downloads/',file_name);
          fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
               if (!err) {
                    lines = data;

                    fs.writeFile("/users/user/Dropbox/Puppeteer/"+folder_name+"/data_"+folder_name+"_"+date+"_.csv", data, function(err) {
                         if(err) {

                                   console.log(err);

                         }
                              console.log("The file was saved!");
                              console.log('Closing Browser');
                              browser.close();     
                         }); 
               } else {
                    console.log('-----SOMETHING IS WRONG-----');
               }
               });
              await page.waitFor(10000); 
     }
})();

The above code works perfectly fine since I have used delays of 10 seconds so that the writing process gets completed, but this is a kind of hack and definitely will not work when the internet connection is slow or the machine is slow. 上面的代码可以正常工作,因为我使用了10秒钟的延迟才能完成写入过程,但这是一种破解,并且在Internet连接速度慢或机器速度慢时肯定无法正常工作。 What I want is that it should first wait for the file to get completely downloaded and then wait for the file writing process to get completed then continue the loop for the next user. 我想要的是它首先应该等待文件完全下载,然后等待文件写入过程完成,然后继续为下一个用户循环。

Add await in fs.readFile & fs.writeFile methods too. 在fs.readFile和fs.writeFile方法中也添加await。

Use 采用

let data = await fs.readFile(filePath, {encoding: 'utf-8'});
await fs.writeFile("/users/user/Dropbox/Puppeteer/"+folder_name+"/data_"+folder_name+"_"+date+"_.csv", data);
browser.close();

instead of 代替

fs.readFile(filePath, { encoding: 'utf-8' }, function (err, data) {
        if (!err) {
            lines = data;

            fs.writeFile("/users/user/Dropbox/Puppeteer/" + folder_name + "/data_" + folder_name + "_" + date + "_.csv", data, function (err) {
                if (err) {

                    console.log(err);

                }
                console.log("The file was saved!");
                console.log('Closing Browser');
                browser.close();
            });
        } else {
            console.log('-----SOMETHING IS WRONG-----');
        }
    });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM