Как разделить вложенные асинхронные функции и выполнить их в нужном порядке?

#javascript #node.js #module #async-await #puppeteer

#javascript #node.js #модуль #async-await #кукловод

Вопрос:

У меня есть асинхронная функция, которая принимает список URL-адресов в качестве значения из проанализированного CSV-файла. Внутри этой функции я использую puppeteer для запуска страницы и перехода по каждому URL. У меня есть две функции — одна для загрузки ресурсов, а другая для проверки, был ли загружен ресурс.

  1. Я хотел бы сначала запустить scriptDownload(), а после завершения его выполнения запустить функцию NetworkProfile() .


  2. Я также хотел бы знать, можно ли выделить эти функции в отдельный файл и применить функциональность экспорта и импорта модулей.

Я не инициализировал функции в прилагаемом коде.

Кроме того, будет несколько асинхронных команд mongodb, которые будут добавлены позже в NetworkProfile() .

Я пытался использовать .then, но ничего не вышло. Всегда NetworkProfile() запускается перед scriptDownload()

Также пробовал экспортировать эти функции как отдельные модули, но в результате ошибка- страница- неопознанная ссылка

 const puppeteer = require('puppeteer');
var fse = require('fs-extra');
var Papa= require("papaparse");
const path = require('path');
var scr = require('./scripts');

async function scripts(x){
    const browser = await puppeteer.launch({ 
        headless: true,
        args: ['--enable-features=NetworkService'],
        ignoreHTTPSErrors:true
    });
    const page = await browser.newPage();
    const client = await page.target().createCDPSession();
    await client.send('Network.enable');
    await client.send('Network.clearBrowserCache');
    await client.send('Runtime.enable');
    await client.send('Debugger.enable');

    async function scriptDownload() {

        page.on('response', async resp => {
            const url = new URL(page.url()).host;
            const url1 = resp.request().url();
            var url2 = path.basename(url1);
            url2 = url2.replace(/?/g, 'amp;q');
            const isScript = resp.request().resourceType() === 'script';
            const isCSS = resp.request().resourceType() === 'stylesheet';
            const isXHR = resp.request().resourceType() === 'xhr';

            if (isScript) {
                let filePath = path.resolve(`./Responses/${url}/js/${url2}.js`);
                await fse.outputFile(filePath, await resp.text());
                console.log('Scripts Downloaded');
            }
            if (isCSS) {
                let filePath = path.resolve(`./Responses/${url}/css/${url2}.css`);
                await fse.outputFileSync(filePath, await resp.text());
                console.log('CSS Downloaded');
            }
            if (isXHR) {
                let filePath = path.resolve(`./Responses/${url}/xhr/${url2}.xhr`);
                await fse.outputFileSync(filePath, await resp.text());
                console.log('XHR Downloaded');
            }
        });
    }

    //network domian
    async function networkProfile() {
        client.on('Network.requestWillBeSent', parameters => {
            const request_url = parameters.request.url;
            var reqname = path.basename(request_url);
            var reqnamereg = reqname.replace(/?/g, 'amp;q');
            const urlloc = new URL(page.url()).host;
            try {
                    /**************************Check if file exists********************************************************** */
                    const jsFilePath = path.resolve(`./Responses/${urlloc}/js/${reqnamereg}.js`);
                    const jsPath = path.resolve(`./Responses/${urlloc}/js/${reqnamereg}`);
                    var locStorage = "null";

                    async function localjs(f) {
                        const existsjs = await fse.pathExists(f)
                        if (existsjs == true) {
                            locStorage = jsPath;
                            console.log(urlloc, reqnamereg, existsjs);
                        }
                        else {
                            locStorage = 'Js does not exist';
                            console.log(urlloc, reqnamereg, existsjs);
                        }
                    }

                    async function local(f) {
                        const exists = await fse.pathExists(f)
                        if (exists == true) {
                            locStorage = jsFilePath;
                            console.log(urlloc, reqname, exists);
                        }
                        else {
                            locStorage = 'File does not exist';
                            console.log(urlloc, reqname, exists);
                        }
                    }
                    if (reqname.endsWith('.js') == 'true') {
                        localjs(jsPath)
                    }
                    else {
                        local(jsFilePath)
                    }
            } catch (error) {
                console.log(error);
            }
        });
    }


    for (var j = 0; j < x.length; j  ){
        try{
            await page.goto('https://www.'   x[j][1], { waitUntil: 'load' });
            const url = new URL(page.url()).host;
            let filePathhtml = path.resolve(`./Responses/${url}/html/${url}.html`);
            await fse.outputFileSync(filePathhtml, await page.content());
        }
        catch(error){
            if(error==='net::ERR_CONNECTION_TIMED_OUT'){
            }
        }
    }

    setTimeout(async () => {
        await page.close();
        await browser.close();
    }, 60000 * 2);
}

file = fse.createReadStream(__dirname   '/test.csv', 'utf8')
function parseData(file, callBack) {
    Papa.parse(file, {
        delimiter: "",  // auto-detect
        newline: "",    // auto-detect
        header: false,
        download: true,
        complete: function(results) {
            callBack(results.data);
        }
    });
}
parseData(file, scripts);
 

Ожидаемый результат будет

Загруженные скрипты

CSS загружен

url, reqname, true(для скриптов) false в противном случае

Ответ №1:

просто поместите их в разные функции и передайте им параметры

 async function scriptx(){

await scriptDownload(page);
await networkProfile(client);


}

async function scriptDownload(page){
}


async function networkProfile(client){
}
 

но я не думаю, что вы делаете это правильно, вы пытаетесь проверить событие внутри функции, которая также должна быть вызвана

Комментарии:

1. Я попробовал это, но не уверен, сработает ли это, потому что, если я помещу функции снаружи, возникнет ошибка ссылки. Например, если я помещу scriptDownload снаружи, страница в page.on не определена. Есть ли что-то еще, например, ожидание завершения события в scriptDownload, а затем выполнение другой функции

2. вы должны передать page в качестве аргумента scriptDownload функции … следовательно scriptDownload(page)