簡體   English   中英

異步等待邏輯返回問題

[英]async for await logic return issue

所以我在試圖弄清楚如何修復下面的剪輯時遇到了一些問題。 截至目前,它正在運行 for 循環的 'request(scanurl,.....' 部分之前返回值。循環確實運行。此外,我不認為 'lines200' var 正在通過櫃台。我是一個學習者,所以任何解釋都將不勝感激。

async function processLineByLine(baseData) {
    console.log('enter async func')
try {
  const fileStream = fs.createReadStream('./file.txt');
  let linesTotal = 0;
  let lines200 = 0;

  const rl = readline.createInterface({
    input: fileStream
  });
  for await (let line of rl) {
    console.log('in loop')
    const scanurl = (baseData.match(/http/gi)) ? (baseData) : ('https://' + baseData + line);
    linesTotal++;

  request(scanurl, {json: true}, function (error, response, body) {
            let statusCode = response.statusCode;
            let htmlBody = body;
            //console.log(htmlBody)
            //console.log(statusCode)
            if (statusCode == "200") {
                console.log('in 2nd if')
                let $ = cheerio.load(htmlBody);
                let titleScrape = $('title').html();
                console.log(titleScrape)
                if (titleScrape.match(/404 | test/gi)) { 
                    console.log('Matched')
                } else {
                        lines200++;
                        console.log(lines200)
                    }
                } else {
                    // Do nothing
                }
            });

        }
        return {
            total: linesTotal,
            count200: lines200,
        }; 
} catch (error) {
    console.error(error)
}

}

router.get('/:reqTarget', async (req, res) => {
    console.log('starting')
    var baseUrl = req.params.reqTarget;
    try {
        console.log('in the try')
    const initTest = await processLineByLine(baseUrl);
    const {total, count200} = initTest;
    console.log(total, count200)
    if (initTest) return res.status(200).send({
        message: 'STATUS 200 COUNT: ' + count200 + ' ' + 'TOTAL: ' + total });

    } catch (error) {
        console.log(error)
    }

});

電流輸出:

starting
in the try
enter async func
in loop
in loop
in loop
in loop
in loop
in loop
in loop
33 0 //this is the return that is two early
in 2nd if
404 | test
Matched
in 2nd if
404 | test
Matched

當您有一個包含異步操作的循環時,您有兩個選擇之一。 您可以並行運行它們,並以某種方式跟蹤它們何時全部完成。 或者,您可以一個接一個地依次運行它們。 看來您的循環可以以任何一種方式構建,但我將說明順序選項。

async/await的出現允許我們在中間使用適當的await來“暫停” for循環。 但是,為了做到這一點,所有異步操作都必須基於承諾,以便您可以await這些承諾。 為此,我已從request()庫切換到request-promise-native庫,它是使用原生內置承諾的request庫的承諾包裝器。 它還有另一個不錯的功能,它會自動檢查 2xx 狀態代碼,因此您不必自己這樣做。

下面是代碼的樣子:

const rp = require('request-promise-native');

async function processLineByLine(baseData) {
    console.log('enter async func')
    try {
        const fileStream = fs.createReadStream('./file.txt');
        let linesTotal = 0;
        let lines200 = 0;

        const rl = readline.createInterface({
            input: fileStream
        });
        for await (let line of rl) {
            console.log('in loop')
            const scanurl = (baseData.match(/http/gi)) ? (baseData) : ('https://' + baseData + line);
            linesTotal++;

            try {
                let htmlBody = await rp(scanurl, {json: true});
                let $ = cheerio.load(htmlBody);
                let titleScrape = $('title').html();
                console.log(titleScrape);
                if (titleScrape.match(/404 | test/gi)) {
                    console.log('Matched')
                } else {
                    lines200++;
                    console.log(lines200)
                }
            } catch(e) {
                console.log(`error on request(${scanurl})`, e);
                // like your original code, this will only log the error
                //   and then continue with the rest of the URLs
            }
        }
        return {
            total: linesTotal,
            count200: lines200,
        };
    } catch (error) {
        console.error(error)
    }

}

router.get('/:reqTarget', async (req, res) => {
    console.log('starting')
    var baseUrl = req.params.reqTarget;
    try {
        console.log('in the try')
        const initTest = await processLineByLine(baseUrl);
        const {total, count200} = initTest;
        console.log(total, count200)
        res.status(200).send({message: 'STATUS 200 COUNT: ' + count200 + ' ' + 'TOTAL: ' + total});

    } catch (error) {
        console.log(error)
        res.sendStatus(500);
    }

});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM